Clean Code:: Method Arguments must be crisp and Encapsulated.


 While writing methods, please pay close attention to the method arguments, This is the one area where the method assimilates the foreign body into its core body. Foreign material is always dangerous, you do not have any control over it, but as an owner of a method, you can put a defensive mechanism aka Validation. Or the Anti-corruption layer of your method.


So, the first tip.

  1. Always put validation on the input argument, you can use java annotations to do the validation.


Now, let's think about what we do in a method after receiving the inputs.


Most methods will do three things.


  1. It will act on the inputs:: so the method will receive the inputs and apply some business logic on them and get a result.


Example::


public void buildReport(String firstName, String lastName, String address, int age, char sex, String dept) {

//build the report

}


If you pay attention to this method we can derive one important thing, the input parameter passed here has associativity, what I meant to say, all input parameters are passed into the method for which reason? Simple, to create the report we need those data. Think logically, when you build a report it will focus on a segment or a context. The Business rule always works to accomplish a feature inside a domain. So if you build a report which needs the above arguments that means you are dealing with the data which are used together frequently because they are in the same domain and same context.


In some cases, I saw some methods which take data from multiple domains and aggregate it and give a view of overall functionality but those cases are less. Mostly a method works on a narrowed feature under a domain. 

Tip 2 :  if your arguments list is long that means you are breaching encapsulations, easily you can tie them under an object as those arguments are often changed or used together, then pass that wrapped object.


I can modify the above method cleaner way



public void buildReport(EmployeeReportContext employeeReportContext) {

//build the report

}



I tied related arguments in the EmployeeReportContext object and make it a Monadic function(A method which takes one argument)




2.  Methods will take decisions based on the arguments:: it will take the arguments and based on the arguments perform some algorithm or business rule to accomplish a feature.




public void serachEmployee(String firstName,String lastName, String latLong, ,Long deptId) {

//build the search query based on the inputs.

}



Again, we can see we are dealing with related input which can be encapsulated in an object.

Now on top of this, another observation is if we pass multiple arguments that means this method is responsible for multiple decision making but we know in SRP Pyramid on a particular level one method is responsible for one responsibility. So the method is breaking SRP, how we can solve this, just segregate out the decision/responsibility by extract method strategy.


I will break the methods into small chunks, in this way by extracting responsibility. Also, reduce the argument list and make each method a monadic Method.



public void searchEmployee(EmployeeSearchInput input) {

Address address = findAdressFromLatLong(input.getLatLong());

Department dept = finDeptbyID(input.getDeptId());

//TODO :: populateEmployeeSearchInput using address and dept

query = buildSearchquery(input);

result = executeSearch(query)



}



3. Holder methods:: These kinds of methods are edge methods that will take the arguments and pass those arguments to next-level methods.


Now first understand why we need this type of method? I like to call them Edge methods like edge service, while we are building an N-tier architecture often we need to pass a good amount of data to the next tier, now if you pass multiple arguments to the next level it will create coupling.


On the other hand, we also do not want to call next tier methods multiple times, then in a distributed system, it will create a Chatty communication where we need to pass multiple data over the network multiple times.


So it boils down to one principal question: how we can pass all data in one shot,on top of that we need to think about the future if I want to pass new data between tiers how to accommodate them because the holder method is a contract between two layers you can’t change method signature often !!!!



So passing multiple arguments in the holder methods is not a solution, as in the future you can change the signature.


So the best way to design this type of method is to create a coarse-grained object (DTO), and pass all data in one shot, or a Map like structure key is the property and value is the object, in both cases, you can easily extend them without breaching the contract.


Example:: The best example is the HTTPRequest object it carries data from UI to controller and servlet doPost and doGet is the holder method which takes the request, extracts parameters from it, and then passes to the next level.


Also, DTO (Data Transfer Object) is doing the same job.



Conclusion:: what we learned from the article?


We learned whatever the method type is, always encapsulate the inputs parameter, never pass multiple parameters in a method, it brings smell in different ways. 


Try to restrict method argument to null-- no foreign body, or one, maximum 3 but over than three is risky, needs to wrap them or need to extract the responsibility from the calling method.


Clean code Tip : SRP is the MEDUSA of Clean code family.

While we are hearing tips on Clean code, the most common tip is maintaining SRP while writing class or methods, in a broader scope Module/Package/Service/API.

But Irony is, SRP is the most powerful but obscured principle in the Design toolbox, this throws a web of confusion and you are stoned by thinking should I use it in the right way or not? That's why I like to call SRP Medusa. Most of the time it succumbs us and we are ending up with anti-KISS code but If we use it in the right proportion, then we can create a cohesive and robust architecture.


It is time to quickly recap the definition of SRP.


“The single-responsibility principle (SRP) is a computer-programming principle that states that every module, class, or function in a computer program should have responsibility over a single part of that program's functionality, which it should encapsulate. All of that module, class, or function's services should be narrowly aligned with that responsibility.”


Let’s demystify the Confusions

  1. What does it mean by SIngle responsibility?

  2. How to define a single responsibility in the Class/Orchestrator method./Package level?

  1. How SRP can be maintained in method level/ Class level/Service level/, isn't it contradictory? If a module/Service maintains SRP then what multiple Classes/methods inside it maintains?


1. What does it mean by SIngle responsibility?

 According to Robert C Martin, Single responsibility means each component has one reason to change, if you have to modify the component for multiple reasons then it breaks SRP. but the question is, what does it mean by reason, how do I find the reason? How can we restrict components to serve just one reason?

let me take an example code snippet to discuss it more, I keep this example confined to the method level.


public void displayEvenNumberfromInput(){

List <Integer> numberList = CommandLine.getNumberInputAsList();

List<Integer> evenList = new ArrayList<Integer>();

for(Integer number : numberList){

if(number %2 ==0){

evenList.add(number);

}

}

System.out.println(“Even List :: ” + evenList );

}

Now read the method carefully and ask yourself, in which reason, you have to edit the method, those will be the reason and we need to separate them out by wrapping by a class/method according to the needs.

The above example invoked a method on an associated class called CommandLIne, but think If requirement changes and we do not want to read from Command line but from JSON, so you have to modify your code. So this is one reason to change.

If I want to change the algorithm, then also I need to change the method, so this is the second reason to change.

At last, rather than print in the console If I want to save the output in File so, this is another reason for the change.

So, I can see the above method has three reasons to change, a small method but doing so much.


2. How to define a single responsibility in the Class/Orchestrator method/Package level?

Take away from the above paragraph is, by asking questions finding the reason for the change. If you are new I would suggest writing a method then checking for the algorithm steps, extracting out the non-related steps, do not separate related step to achieve granular level SRP, it will create Code smell and increase coupling, 

Now for architecting service or class study the acceptance criteria and encapsulate non-related acceptance criteria.

Another approach is trying to find out commit which classes are often committed together pay a closer look at them any find dependency you can extract out from them, or in a class change the field name and found what are the methods gives you the error, probably they are very related and closed, so avoid to segregate them in a separate class, again these are just strategy but to use SRP in the right proportion, not making code too granular, maintaining KISS and achieving cohesion need well-versed knowledge in the domain, and architecting.

 sometime you will see some methods/Class are breaking SRP but if you pay closer look reasons are strangled together so no need to separate them out it will increase the overhead of maintainability cost,

Example::  Like if the minimum balance is over some amount then do the debit operation, here validation and debit operation are linked together so let it be in the same class.


So, domain knowledge and what context you are writing the class/methods is important, initially while architecting a class/module may be wrong in the long run but next time when you need to touch the component try to understand why you need to touch that component and separate out that concern. So Refactor is a must - to get a proper SRP, you have to do multiple refactoring, so take time, take a buffer in your story point. Refactor is a first-class citizen while you doing code


Let see How we can curb out the responsibility from the last example?


  public void displayEvenNumberFromInputSource(){         

          List<Integer> numberList = processFactory. processInputSource();

          List<Integer> evenList = algoFactory.findEven(numberList)

          displayable.display(evenList);

     }

Now I abstract the three reasons and separate them out into different classes, I am assuming there are multiple Inputs Source we need to support so I separated it into a different class, If that is not the case only we have to read from the command line, I will separate them in a separate method in Same class, Now the hardest question comes, you may say my class breaks SRP as it handles three concerns even the orchestrator method displayEvenNumberFromInputSource handling three separate concerns so sure breach of SRP.

With this context, I will dive deep into the most obscured part of SRP.


3. How SRP can be maintained in method level/ Class level/Service level/, isn't it contradictory? If a module/Service maintains SRP then what responsibility Classes/methods maintain?

I personally think, there is one part missing in SRP definition, the term hierarchy/Level, SRP does not make sense if you apply it to a specific point it is a range.


It is like a Pyramid, like our Food chain Pyramid. In a particular domain space if we visualize it using a bottom-up approach, it is starting from method level then responsibility merging in Orchestrator method, then Class, then package, then service/module level. It goes from more specialization to generalization in an upward direction.


So, in a top-level, it will do one responsibility which consists of multiple sub responsibilities, and each level of the SRP pyramid delegates the responsibility to the next level and it is continuously going on until it reaches the bottom level until each method handles a single responsibility.

But at the same level of the SRP pyramid, no component will perform more than one responsibility of that particular level. Each component level must not cross each other then it is breaching the SRP pyramid level and your higher-order component will know the lower order components, so against the Dependency Inversion principle. Only the upper-level talks to the next level through encapsulation.


Think about the HR department, what is its job in the organization -- managing Human resource, In an organization This is one of the SRP Pyramid Tower, Payroll, Finance are the different SRP Pyramid Towers. Each tower talks to the other tower through an Organization in-house API contract and each tower specifically handles one broad responsibility of that organization.


Now if we deep down to HR SRP Pyramid, next level we can have multiple sub responsibilities like managing different geography, different policies, so each time you deep down to SRP Pyramid you are dividing the responsibilities to sub responsibilities and give it to a more specific component to do that job.


That is the main essence of SRP, Divide, and conquer the work.

In SRP Pyramid, You can not compare top-level component with bottom level and then thinking top-level component is breaking SRP, you are then comparing Apple with Oranges.





So I would like to rephrase the definition of SRP.

“The single-responsibility principle (SRP) is a computer-programming principle that states that SRP starts with a SRP Pyramid , where a module, class or function in a computer program placed in a level and in that level they have responsibility over a single part of that program's functionality, which it should encapsulate from the next level . All of that module, class or function's services should be narrowly aligned with that responsibility.”


Or in a simple 


In SRP Pyramid each component in a Level has one reason to change. 

Techniques for reducing Tight Coupling

“Tight Coupling is Bad” How many times you have heard this word from your seniors. Probably many many times.
But why Coupling is bad what are the implications comes if you do tight coupling?
What is actually a Tight coupling?
How we can fight with it.?
In this tutorials, we will dig the answers.

Coupling: In a simple term coupling is when a Class or Interface dependent on another class/interface i.e has a HAS-A relationship.

Example :

Class Vehicle{

private Wheel wheel =new Wheel();

}

In above example, Vehicle is dependent on Wheel, Which means without creating Wheel Object we can’t create Vehicle Object if anything goes wrong while creating Wheel Object vehicle will never be created. Also if we need to test Vehicle, first Wheel Object has to be created then Vehicle can be tested. Without, Wheel Vehicle has no existence. This type of coupling is called Tight Coupling, We know Vehicle must contain Wheel, To make the statement more generic sometimes we have requirements where a class must have to contains other classes to fulfill its purpose, they can't-do thing independently. So Coupling is inevitable, it can not be avoided but by programming technique we can make it pluggable in such a way so that we can reduce the degree of coupling so Dependable and Dependent class/interface can be changed without impacting each other. We called this technique as Loose coupling. I will show you some techniques which reduce the coupling between Objects.

Creation of Objects : Often while we doing coding we direct create the dependable Object instance, either in a init method or in Constructor or supply it through setter/constructor. But it is always risky. Once you have done that, Then you lose the flexibility if requirement changes in future you have to change the Dependent Object to accommodate the change in dependable Object. Let say All Ford cars use MRF Wheel So they are dependent on MRF wheel, Now if they change the mind and want to use Another company’s wheel then they have to change all car's Wheel Object creation so it is against the Open-Close principle.

Ex.
public Class Ford{
MRFWheel wheel;
Ford(MRFWheel wheel){
this.wheel =wheel;// replaced by new JKWheel()
}




}

So the best practices would be If you think dependent object will be changed frequently or may have multiple implementations always create an Interface and use that interface as a reference so anytime you can change the implementation without affecting the dependent class. But if you are sure about the dependent Objects behavior will not change then unnecessary don’t create interface it again against YAGNI and KISS.

IWheel{
//wheel related methods
}

public class Ford{
IWheel wheel;
Ford(IWheel wheel){
this.wheel =wheel;// replaced by new JKWheel()
}




}

Assuming MRFWheel and JKWheel are the subclasses of the IWheel

new Ford(new MRFWheel());
new Ford(new JKWheel())



Use Static factory method for creating Object : While creating an Interface for multiple implementations is good as you can change implementation dynamically. But if the dependable Object implementation is changed then again you have to change the all dependant Object which again breaks the Open/close principle.

Say Now Wheel take Air Pressure as a Constructor arguments then the caller of the Ford car has to change its logic, as multiple cars have dependencies on Wheel every implementation will break due to this change.


new Ford(new MRFWheel(AirPressure pressure));
new Ford(new JKWheel(AirPressure pressure))

The problem is we do not centralize the Object creation so all the caller has a responsibility to create the Objects and when the project grows it is a tedious job to find all references and fix them in case of a change in business logic in dependable Object. We certainly reduce our effort, if we use a Static Factory method to create the instances, So we centralize the creation of dependable object all dependent objects refer static factory method to get the dependable Object.So if any implementation details change it will only affect the Static factory method, Unless the method signature of the Static factory method is changed.

public static IWheel createWheel(WHEEL wheel){
if(WHEEL.mrf.equals(wheel)
new MRFWheel(AirPressure pressure)
}
else if(WHEEL.JK.equals(wheel)
new JKWheel(AirPressure pressure)
}else{
New DumyWheel(AirPressure pressure)
}

calling:

new Ford(WheelFactory.createWheel(WHEEL.mrf)));
new Ford(WheelFactory.createWheel(WHEEL.JK)));



Don’t take dependable Object Responsibility : Often knowingly or unknowingly, caller take the responsibility of dependable Object, which is breaking the encapsulation and it is the most common coding mistake I have seen, Not judging the Cohesion properly and it breaks another principle Tell Don’t Ask. Which increases unnecessary coupling and gradually your code not welcoming any future changes. Let's take a Simple example how we take dependable Object responsibility.  Say Ford car has a method which shows the specifications of the car in very detail manner. So when it shows the Wheels Specifications often we do code like this in Ford Class.



public void FordSpecification(){
//Ford car specific specifications
//then
wheel.getAirPressure();
wheel.getManufactureDate();
wheel.getBrandName();

}

But it has a severe problem if in future Wheel specification is changed if it adds or removes any attribute it has a direct impact on Ford class, So all Ford Car classes have to be changed to incorporate the specification changes of the wheel.

It is wheel specification changes so why Ford class would be the sufferer?
Because while coding we did not understand the Wheel class responsibility, It is wheel class responsibility to provide specification through a specification method which uses by the Ford.

In Wheel class

public void specification(){
wheel.getAirPressure();
wheel.getManufactureDate();
wheel.getBrandname();

}

In Ford Class

public void FordSpecification(){
//Ford car specific specifications
//then
wheel.specification();

}


If wheel specification changes it does not impact the Ford class.


Try to reduce Hide-coupling :

Hide Coupling means from the API, you can’t understand there is and Dependency inside it.

It is a common programming technique where we hide the coupling from the user, Like create necessary Objects inside init method or constructor. I am not saying this is bad but , When you hide a Coupling think very carefully , If the Object is a kind of Utility, Connection pools, Worker thread that is fine but if it is a normal business Object, always provide an option for setting the Object from Outside, So user can set a Dummy or Mock Object while testing, Unless as a developer it is very hard to track down why the Object is not created as user does not aware of hiding coupling



Take the first example again

Public Class Ford{
MRFWheel wheel;
Ford(){
this.wheel =new MRFWheel();
}




}


From the API of Ford, it is impossible to say Ford has a dependency on MRFWheel. You will discover it in runtime if  MRFWheel Object is not created from the stack trace. But if you change the implementation.


Public Class Ford{
IWheel wheel;
Ford(IWheel wheel){
this.wheel =wheel;// replaced by new JKWheel()
}




}

Then we can inject a DummyWheel while unit testing the Ford specific method.


Conclusion : Tight Coupling always creates a Big Ball of Mud. And gradually loses the flexibility to incorporate changes. Always take a closer look for coupling while writing code-- A silly mistake can cost you very much in near future. If you take above best practices most of the time you will be on safer side.