Object-Oriented Design – Is Optional Data in Constructor Bad Practice?

object-orientedobject-oriented-designtypescript

Currently I have a model class that represents a user.
This class has a constructor that takes an object with all user properties, used for example, when creating the user. In this case I instantiate the model passing it the necessary information so it's constructor can do the job, then it will use its own "createUser" method. Fine.

But in some cases, I don't need to pass all those information to the constructor.
For example the model has an "UdpateCustomUserName" method that just need userId in order to instantiate from the db and perform this method and update a single field from a single already existing record in the database.

The way I dealt with this is make the "properties" information needed by the constructor optional, so when I need to call "UdpateCustomUserName" I just pass to the model the ID and I can instantiate and reach this method.

Is this the proper way of doing it ?
Or is it a bad practice to have optional constructor parameters ? In this case i would extract "UdpateCustomUserName" and keep it in the same module but as a standalone.

Best Answer

Optional parameters is not a bad practice, definitely not, but sometimes the optional parameters may be optional solely because of what the class does.

You arrived at a problem which is a result of a bad design. You are trying to figure out how to ignore certain properties of a model if you don't use them. The problem is, you are mixing responsibilities of classes together and trying to create a class which knows and does many things. That is pretty bad and might cause you troubles later on, because it will be very difficult to reuse the class in a different environment, for example.

Obviously, when you have a class which can do many operations, there will be a situation where one operation will not need everything that the class contains, but is required for other operations.

What you should be after is splitting your current class into several smaller classes, each being responsible for only one thing and make the class do the thing well. You could have a UserModel, which could be an actual representation of a user in your code, you could then have some sort of service, which would accept the user and do an operation on it. Obviously, if the operation required database access, you would need to provide a class acting as the database accessor to the service class as a dependency as well.

I personally would opt for refactoring the monolithic class into several smaller ones, each taking only the dependency (or dependencies) which it really needs.

Related Topic