Let's say I have a User
model defined. It makes sense that methods for retrieving certain fields of this model lives in the model file.
My question is where something that generates a unique UUID, or username should go. If I have a method for generating a unique username and it isn't specific to a particular instance of a User, does it still belong in the model file? Or a utils file? It seems wasteful to stash in a utils file, but it doesn't seem like it should go in the Model file either.
-
1Just an additional hint: make sure the functionality you are talking about here is REALLY not part of your model. Perhaps the username generation is governed by domain specific policies (uniqueness is a hint)? Avoid hard references to static methods if you want to mock/stub the logic in tests (for example to achieve reproducible results). It's quite reasonable to create a service doing that non-trivial work and this service should then get injected into the class where you need it.Hero Wanders– Hero Wanders2019年02月15日 11:55:38 +00:00Commented Feb 15, 2019 at 11:55
3 Answers 3
Does the language you're using support static methods? If the behaviour is definitely specific to the User then it should either be a static method of User or a method of an associated helper class (e.g. a UserFactory or similar). If nothing about the method is particular to the User (e.g. simply generating a GUID) then it's not really a part of a user. In that case it's more of a utility. It depends a lot on the full details of your design if the right place for that is a Utilities file or not but in general the rule is, does it depend on properties of User or is it a separate thing that you just happen to be using for Users today and perhaps will want to use for, say, Widgets, tomorrow?
-
This was helpful— mostly because the random ID is just a random base32 string. So I created a crypto utils file with some helpers for generating random bytes and strings instead of putting it somewhere related to the user.aroooo– aroooo2019年02月15日 19:34:58 +00:00Commented Feb 15, 2019 at 19:34
There are several options to place such methods, and what is "best" depends heavily on the system you are developing, the specific method, and the context .
in smaller programs, or as long as you have very few of such methods, an "Util" class can be acceptable. However, such classes tend to become a container for lots of unrelated stuff, which can easily get messy when you don't clean up early enough
a small method which generates automatically a Username could be also a static method of the
User
classif you have several such methods belonging to a certain topic like "UUIDs", but no model class "UUID", an acceptable solution could be something like a
UuidUtil
class or module, with only static methodshowever, if the method itself needs several helper methods, a better alternative may be to design something like a
UserGenerator
orUUIDGenerator
class.when the method belongs to a certain use case like "new user creation", then there is probably a service class like
UserCreationService
, and that's probably a good place for it
So pick your choice.
Use static methods to access static data. Use instance methods to access instance data.
However some think when there is no data to access, static is the only way. They are wrong. When there is no data don't use data to decide.
Data access simply isn't the only difference. The other difference is polymorphism. Many languages have no support for polymorphism for methods that are static but do for instance methods, even if those instances hold no data.
So don't fall into the trap of thinking no data means make it static. It's simply wrong. Think about what your needs are.