In this article, we will be discuss about a design principle called Tell, Don’t Ask. This principle is aimed at designing the classes in such a way that, when they are used, instead of querying the state of its object/instance and performing the operation (based on the output it receives), the class should handle the logic itself.
In other words, it means, the class should take the decision itself, rather then client code telling it what to do. So let’s discuss with a code sample which violates the principle and than will implement the same using this principle.
Consider the following piece of code. Here, we have the following business logic implemented.
Here, we check for the discount applicable on the vehicle. If it is greater than
5%, we subtract
5000 from the actual price else
3000, as a discount to the user. We also have a
net price price defined for the vehicle. After applying the discount, if
net price is more than this
base price, we can further provide free accessories else we do not.
This type of code will have following issues:
1. If we have same type of logic in other areas of application, changes in the logic will require changes in all the locations.
2. Client code is now aware of the business logic to calculate the cost of the vehicle.
3. Some of the member functions/properties are unnecessarily exposed as public members, to the client code.
This is where we can use the Tell, Don’t Ask principle. So we change our code to shift the entire logic into the
CostCalculator class and pass the required data to it. It calculates the net price and based on results, it decides whether it further needs to make a call to the
ApplyAccessories() method or not. Our code now changes to:
So in this case, the entire calculation logic, along with logic to add accessories, is inside the
CostCalculator class. We simply provide the required data as input to this class. Moreover, the
ApplyAccessories method is now converted into a
private method and client code also has no idea of the cost calculation business logic. Client code will simply pass the data to the
CostCalculator and rest will be done by its
NetCalculation method. In other words, we are telling the
CostCalculator instance to perform all the calculations, rather than querying its current state and performing any operation. So this was about the Tell, don’t ask principle.