Helpful Clean Coding Tips

Güneş Maboçoğlu
5 min readDec 22, 2020

--

I will try to mention some software design topics which I think are important. These are:

  • Law of Demeter
  • Single Responsibility Principle
  • Composition over Inheritance
  • Primitive Obsession
  • Listen to Tests
  • Use Dependency Injection Technique

Law of Demeter(LoD)

LoD is a design guideline for developing software whose rules and benefits can be summarized as:

Rules (based on Wikipedia):

  • Each class must be able to access to another class only the information and resources that are necessary for its legitimate purpose.
  • Each unit should have only limited knowledge about other units.
  • Each unit should only talk to its friends; don’t talk to strangers.

Benefits:

  • It gives full control over class properties. You cannot change any property from outside of its class context.
  • It makes loose coupling relations over classes.
  • It makes it easier to refactor code.

Let’s think about that we are working on a client application. The classes in the project are as follows:

I only want to add NumericFilter to the PasswordView. To make this, I have to add the filter to EditableTextView and have to know how EditableTextView keeps filters.

  • All of this information creates an unnecessary dependency between Screen and EditableTextView. Thus these classes are coupled now. Whenever we want to change PasswordView or EditableTextView filter mechanism, we must update the Screen class also.
  • How can we add restriction to the functionality of adding a filter to PasswordView or EditableTextView? For example, how can I prevent adding AlphanumericFilter to PasswordView? As you can see we have no control over filters.

How must we implement these classes?

  • I don’t need any knowledge about EditableTextView to use PasswordView.
  • I can have full control over adding filter.
  • Any changes to EditableTextView implementation do not affectPasswordView api.

Single Responsibility Principle(SRP)

What does responsibility mean in the SRP concept? Assume that we need a telephone class. While we creating it, we want to stick by the SRP. That’s why let’s start with the writing responsibilities of a telephone.

  • Must be able to send text messages.
  • Must be able to make a call.
  • Must be able to connect to the internet.

It goes like this. As you can see, there are many responsibilities. So how can we stick to the SRP in the presence of a lot of responsibilities? Could we be making a mistake when defining the concept of responsibility?
Let’s look at Robert C. Martin’s definition:

Martin defines a responsibility as a reason to change,
and concludes that a class or module should have one, and only one, reason to be changed (e.g. rewritten).

It means implementations of each responsibility(or we can call this duty) must be defined in somewhere else.

In case these functions need to be changed, we have to refactor the Telephone class. That’s it, it violates the SRP. To be compatible with the SRP, we have to construct Telephone class as follows:

Any of VoiceSignalManager, TextMessageSignalManager, or NetworkManager implementation changes do not affect to Telephone class. So our Telephone class is compatible with the SRP.

All of these are eligible to function definitions as much as class.

Composition over Inheritance

How can we decide to choose between composition or inheritance? Which one is the best practice? It is quite simple, the answer relies on this question, which kind of relationship is there between classes, is there a “has-a” relationship or an “is-a” relationship? If the answer is there is an “is-a” relationship then the best practice is inheritance, otherwise composition.

  • What is an “is-a” relationship? A taxi is a vehicle also a bus is a vehicle too. (inheritance)
  • What is a “has-a” relationship? A taxi has an engine. (composition)

It seems very easy to decide but in practice it’s not that easy. Many times we go in the wrong direction. At which point do we make the mistake?

Let’s continue with another example. Imagine we are working on a client application that has different screens.

There is TextInputView class:

Then let’s add a day and night theme to it now.

Is there something wrong with the class structure above? If there is then what is it? Let’s answer the “is-a” and “has-a” questions.

  • Are NightThemedTextInputView and DayThemedTextInputView a ThemedTextInputView? Yes.
  • Is ThemedTextInputView a TextInputView? Yes.
  • Is Theme is a TextInputView? No.
  • Is DayTheme is a ThemedTextInputView? No.
  • Is NightTheme is a ThemedTextInputView? No.
  • Has TextInputView a Theme? No.

Here starts our mistake…

  • Has ThemedTextInputView a Theme? Yes.
  • Has DayThemedTextInputView a Theme? Yes.
  • Has NightThemedTextInputView a Theme? Yes.

If ThemedTextInputView, DayThemedTextInputView and NightThemedTextInputView all have Theme then why we inherit from ThemedTextInputView to construct NightThemedTextInputView and DayThemedTextInputView? Even if NightThemedTextInputView and DayThemedTextInputView are a ThemedTextInputView, we cannot inherit Theme attribute. This is the trap which is seen many times. In order not to fall into this trap we need to know we cannot inherit a function that has a “has-a” relationship.

So ThemedTextInputView should be like this:

Primitive Obsession

It shortly means leaving type safety out. Credit card, email, date, password, URL and many others. This kind of information mostly stored as String. All kinds of logic which are related to all of this information mostly put in Utility classes.

Alright, why is putting this kind of information in Utility classes wrong, what is the best practice in this situation? Let’s think about date information.

Date information could be stored in many forms, such as only day, just month or whole date. It could be some part of the whole date, or complete. It could have different formats too. Can we understand all of this information just by looking at the variable name?

var creditCardExpirationDate: String

If you know about credit cards, you can easily say that the “creditCardExpirationDate” variable has to store month and year. But can you tell what its format is, is it “11/2024” or is it “11/24”? So this is not type-safe. Therefore we need to create CreditCardExpiryDate which is tailored for this purpose.

If we are working on a date, there must be a Date class. This kind of information has more attributes than primitives thus we have to define them as a type.

Listen to Tests

If writing a test is difficult, then you must think twice about your class structure. The cause is most likely because it violates one or more software concept(this is often the “single responsibility” rule). This tells us writing unit test is the best teacher about clean coding.

Use Dependency Injection

Use dependency injection to make it easier to apply the rules and techniques above to your project.

  • It makes circular dependencies visible.
  • It makes the classes loosely coupled.

Use dependency injection framework.

  • It reduces boilerplate code
  • It makes class creations easier.

--

--