Agile and SOLID


Introduction#

The core principal of a agile team is to be able to learn and react to what the team has learned as the project progresses. This article is about the requirement for engineers to take part in that process. Namely reacting to what the team has learned. As Engineers we are expected to be able to implement new ideas and experiments in the system quickly. That means we need to build code that is easy to change. This is easier said then done. Thankfully we have the benefit of being able to stand on the shoulders of giants. Learning and pulling from the thought leaders in our industry today and the past. The single most powerful tool that we can use to help us make code that is easy to change are the SOLID principles.

Origins of SOLID#

The SOLID principals were first introduced in 2 papers by Robert C. Martin(Uncle Bob). One was written in 2000 named Design Principles and Design Patterns. The other was written in 2005 named Principles of Object Oriented Design. Uncle Bob describes the cause and effect of code rot in a system overtime. Pointing out how, even well designed systems, degrade as new members of the team are introduced, requirements change rapidly, or requirements change in unpredicatable ways. These cited causes of degradations in code quality are ineveitable. although the type and intensity of each of these varies, the fact that they will exist does not. The focus must then becomes how to defend against these degradations. Uncle Bob compiled ideas from other thought leaders of the industry and his own experience to invent a succinct mnemonic acronym to help us remember.

The Single Responsibility Principle (SRP)#

Stated Principal#

A class should have only one reason to change

Origin#

Although Uncle Bob first introduced this idea, it was based off of principle of cohesion, as described by Tom DeMarco in his book Structured Analysis and System Specification(1979), and Meilir Page-Jones in The Practical Guide to Structured Systems Design(1988). Uncle Bob outlines much of this history in the article The Single Responsibility Principle.

Description#

SRP focuses on creating classes that when changed, do not require consideration of how they effect otherwise independent systems. For example, if you have a User class and this class is used by both the shipping and the billing systems, then the shipping system could require a change that would break the billing system. A conflict emerges because there are two responsible parties that have the right to change the functionality but now cant due to the requirements of the other. SRP states that these should be different classes. That way each system can change their class without effecting the other.

The Open/Closed Principle (OCP)#

Stated Principal#

We should write our modules so that they can be extended, without requiring them to be modified.

Origin#

OCP was first published by Bertrand Meyer. This stands to follow as he was also the first person to first publish the command pattern and the invention of the Eiffel Language.

Description#

OCP means that we need to abstract. We should avoid conditional statements in our code wherever possible. A conditional statement implies that it needs to know all of the options. However, the options will change overtime. Requiring you to modify the function in order to gain additional or different functionality. It also means that you are altering code that could effect other options that were to be untouched during this change. Possibly causing bugs in other parts of the system. Instead what should be done is that the choice of what code to be ran must happen elsewhere and then passed into the function as an abstracted arguement. That way additional options can be added to your code without having to alter the existing method.

The Liskov Substitution Principle (LSP)#

Stated Principal#

Subclasses should be substitutable for their base classes.

Origin#

LSP was introduced by Barbar Liskov. She won the 2008 Turing Award for her outstanding contributions to our field and his currently a MIT Institute Professor as of writing this.

Description#

LSP states that the contract of the base class must be honored by the derived class. Thankfully for us many languages provide this for us and we can simply use it. However, its important to understand what this means. If you have a class named Student and it inherits from a class Person then that means that a Student can do everything a Person can do, with the additional functionality of Student.

Even though most Object Oriented Languages we use guide us to correct behaviour, we can still find ways to break this principle. Lets say the Student class begins to violate the contract of the Person class by not allowing some of its functionality to take place then we would no longer be abiding by LSP. In this case Uncle Bob has a statement that I really like. He infers that common fixes to this problem would be to begin introducing if statements to handle the fact that Student can do everything a Person can do. He continues by stateing following:

Thus, violations of LSP are latent violations of OCP

The Interface Segregation Principle (ISP)#

Stated Principal#

Many client specific interfaces are better than one general purpose interface

Origin#

ISP was first introduced by Uncle Bob while consulting at Xerox. Where the Xerox software had every job that it could do running through a singular class. Making otherwise independent tasks have to know about each other and take each other into account. Uncle Bob first used what is now called ISP to break apart the functionality of that class into reasonable interfaces. This allowed them to the implement ISP and effectively decouple the job class.

Description#

ISP tells us that supporting a single all knowing interface at any level of our application makes maintaining that interface very difficult. We should instead embrace having purposed interfaces and then allowing possible overlap between them. This way we create space for changes without effecting parts of the system that are not intended. For example if we had a animal class. That class shouldnt have an interface named IDoAnimalThings. It should instead have multiple interfaces based on reasonably grouped activities. Perhaps in this case they would be ICanHunt and ICanHide. They both require the ability to lay down, but this gives us the freedom to grow the capabilities of one without having to effect the other.

The Dependency Inversion Principle (DIP)#

Stated Principal#

Depend upon Abstractions. Do not depend upon concretions

Origin#

This principle was introduced by Uncle Bob himself in an article named Object Oriented Design Quality Metrics: An analysis of dependencies(1994)

Description#

DIP is the primary mechanism of The Open/Closed Principle (OCP). Uncle Bob phrases succintly:

Dependency Inversion is the strategy of depending upon interfaces or abstract functions and classes, rather than upon concrete functions and classes.

Lets try to sort out what he is saying here. Would it make sense that a function that does addition of two numbers should break if the source of the two numbers changes? Of course not. The source of the numbers shouldnt be a dependency on the addition of two numbers. The same idea applied to larger systems get more complicated. We can still reason about it at every layer though. Should a website break if a database type changes? no. You can ask this same question about any relationship in the system and you will be able to quickly understand how a system should behave. How does DIP help us with that though? It states that we should be relying on abstractions and interfaces. For example, if I had a method named getUser. If that method had a direct connection to the database, then a change to the database would effect the getUser method. In otherwords, getUser is depending on the database. However, If we invert this dependency by having getUser ask an interface for information from the database, then our method doesnt need to know anything about the implementation. The Database can change all it wants and getUser can be none the wiser.

Conclusion#

Agile is about learning quickly and reacting to what we have learned. Writing code that can be quickly and easily changed to react to what we have learned is paramount to agile. The SOLID Principles that we just covered is a excellent guide to help us achieve a code base that can react quickly to the changing environment that we are required to embrace.