Journey of a Techie

SOLID (Design principles – 3)

Advertisements

Let us explore how we can implement Solid in our day to day execution.

S – Single Responsibility Principle

What does this mean?

It implies that each class should have a purpose. The reason why the class exists should be clear and there should only be one reason. This is also read as, there should only be one reason for the class to change.

How to know if the class is following this principle?

Use Javadoc to describe what this class does. The documentation should clearly layout the responsibilities for the class, and pay special attention whenever using the keyword “and” ,”or” and “.” while describing.

This will lead to multiple classes?

Most of the programming languages have low footprint of classes and objects. Creating multiple classes / objects does not hamper performance. In maximum cases it is a “perceived performance slowdown” and not “actual performance degradation. Unless you are working on a system where the RAM and CPU cycles are limited, it is better to make code more readable.

How does this rule benefit?

Have you ever struggled when the responsibility in you day to day work was not defined? Or when a request made to you was not clear? In those cases you try to solve for using your best judgment possible, still you end up short of the expectation. Wouldn’t it be better if the responsibility was clear? Same goes with classes. If your class knows what it is meant to do, it can do it properly.

Other benefits include having a better abstraction, more cohesive code, and much more code reusability. Having the clear definition would also lead to making changes easier. Testing the change easier. Isn’t that what our goal as developers should be? To make code adaptable?

What kind of classes can we have?

There could be multiple classes each having its own set of responsibilities. Some of them (not comprehensive) are :-

  1. Request – An object that is expected as a request in API
  2. Response – An object that is expected as a response from the API
  3. Aggregator – A class that aggregates function class. It is responsible for delegating function calls in the correct order.
public Object executeSomeSpecificAction(Object requestObject) throws ValidationFailedException {
    requestObject.validate();
    Object validatedObjects = RequestValidator.validateBusinessCases(requestObject);
    Object moreData = DataFetcher.fetchMoreDataFor(validatedObjects);
    Object businessData = BusinessLogicExecutor.executeBusinessLogic(moreData);
    DataTransactionmanager.saveData(businessData);
    Object responseObject = Convertor.createResponseObject(businessData);
    return responseObject;
}

The above function is only aggregating various other functions from other classes.

  1. Validator – This can perform specific business logic validations on a specific type of object . Such as you want to perform if the given input already exists in your database or not etc. You would want to do the request value validations inside the request object only, to maintain encapsulation.
  2. Data layer – This class knows how to manage data. This would take a object and understands how to delegate to specific tables.
  3. Respository – This class knows how to manage a single table.
  4. Converter – This class knows how to convert one object to the other object.
  5. Util – This class provides specific utility functions.
  6. Business logic – Each class provides a specific business use case execution.
  7. API – Each class defines the API request.

If we try to break the classes in terms of layers and responsibilities, we get the following.

Classes and their responsibilities

This covers the single responsibility principle, one of the most important factor that makes the code readable and maintainable.

Will share my thoughts on the other principles in upcoming post.

Advertisements

Advertisements