/ clean-code

[Clean Code] Designing Classes

In this series of posts , I would try to share with you some of my highlights on Clean Code Chapters.

In this post , I will try to share with you my own highlights on Classes Design chapter on Clean Code.

  • Classes should be small.

  • Classes should be smaller than that :) .

Even a small class like this seems like a bad example because it has multiple responsibilities.

public class SuperDashboard extends JFrame implements MetaDataUser
    public Component getLastFocusedComponent() 
    public void setLastFocused(Component lastFocused) 
    public int getMajorVersionNumber() 
    public int getMinorVersionNumber() 
    public int getBuildNumber() 
}
  • Class names including weasel words like Processor or Manager or Super often hint at unfortunate aggregation of responsablities.

  • We should also be able to write a brief description of the class in about 25 words,
    without using the words “if,” “and,” “or,” or “but.”

Class Orgnanization

How to organize your class ?

Following the standard Java convention, a class should be order in the following way

1- Variables :

a- public static constants.
b- private static variables
c- private instance variables.

2- Functions :

a- Public Functions
b- Private utilities called by a public function right after the public function itself.

Important Principles

The Single Responsibility Principle :

ِِA class or module should have one, and only one, reason to change (One responsibility).

The previous class has two reasons for change :
First, it tracks version information that would seemingly need to be updated every time the
software gets shipped. Second, it manages Java Swing components

We should separate versioning information.

public class Version {
    public int getMajorVersionNumber() 
    public int getMinorVersionNumber() 
    public int getBuildNumber() 
}

SRP is often the most abused class design
principle. We regularly encounter classes that do far too many things. Simply , getting software to work and making software clean are two very different activities.

Cohesion

Classes should have a small number of instance variables. Each of the methods of a class should manipulate one or more of those variables.

A class in which each variable is used by each method is maximally cohesive.

Keeping your functions as short as possible in addition to maintaining a short parameter list will make you in need for creating shared parameters (instance variables) within your class.
Unfortunately, this also means that our classes lose cohesion because they accumulate more and more instance variables that exist solely to allow a few functions to share them which should make us think about splitting them.

When classes lose cohesion, split them !

Organizing For Change

For most systems, change is continual. Every change subjects us to the risk that the remainder of the system no longer works as intended. In a clean system we organize our classes so as to reduce the risk of change.

A client class depending upon concrete details is at risk when those details change. We can introduce interfaces and abstract classes to help isolate the impact of those details.

Dependencies upon concrete details create challenges for testing our system. If we’re building a Portfolio class and it depends upon an external TokyoStockExchange API to derive the portfolio’s value, our test cases are impacted by the volatility of such a lookup.
It’s hard to write a test when we get a different answer every five minutes! so we can build it on an interface so that we can create a testable implementation that emulate TokyoStockExchange.

Final Note :

You don't need to rewrite your code to make it clean. The change is made by writing a test suite that verifies the precise behavior of the
first program. Then a myriad of tiny little changes are made, one at a time. After each change the program is executed to ensure that the behavior didn't not change. One tiny step after another, the first program would be cleaned up and transformed into a better state.

We want our systems to be composed of many small classes, not a few large ones. Each small class encapsulates a single responsibility, has a single reason to change, and collaborates with a few others to achieve the desired system behaviors.