Let's say, for example, you have an application with a widely shared class called User
. This class exposes all information about the user, their Id, name, levels of access to each module, timezone etc.
The user data are obviously widely referenced throughout the system, but for whatever reason, the system is set up so that instead of passing this user object into classes that depend on it, we're just passing in individual properties from it.
A class that requires the user id, will simply require the GUID userId
as a parameter, sometimes we might need the username as well, so that is passed in as a separate parameter. In some cases, this is passed to individual methods, so the values are not held at the class level at all.
Every single time I need access to a different piece of information from the User class, I have to make changes by adding parameters and where adding a new overload is not appropriate, I have to change every reference to the method or class constructor as well.
The user is just one example. This is widely practiced in our code.
Am I right in thinking this is a violation of the Open/Closed principle? Not just the act of changing existing classes, but setting them up in the first place so that widespread changes are very likely to be required in the future?
If we just passed in the User
object, I could make a small change to the class I am working with. If I have to add a parameter, I might have to make dozens of changes to references to the class.
Are any other principles broken by this practice? Dependency inversion perhaps? Although we're not referencing an abstraction, there is only one kind of user, so there isn't any real need to have a User interface.
Are there other, non-SOLID principles being violated, such as basic defensive programming principles?
Should my constructor look like this:
MyConstructor(GUID userid, String username)
Or this:
MyConstructor(User theUser)
Post Edit:
It has been suggested that the question is answered in "Pass ID or Object?". This does not answer the question of how the decision to go either way affects an attempt to follow the SOLID principles, which is at the core of this question.
I
inSOLID
?MyConstructor
basically says now "I need aGuid
and astring
". So why not have an interface providing aGuid
and astring
, letUser
implement that interface and letMyConstructor
depend on an instance implementing that interface? And if the needs ofMyConstructor
change, change the interface. -- It helped me greatly to think of interfaces to "belong" to the consumer rather than the provider. So think "as a consumer I need something that does this and that" instead of "as a provider I can do this and that".