Architecture - SOLID

SOLID Principles

Solid is an acronym for the following:

  • Single Responsibility Principle
  • Open Closed Principle
  • Listkov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

These are described below

Single Responsibility Principle

Open Closed Principle

The example given was an insurance industry. They are adding a new type of insurance – ex Flood Insurance. Someplace – probably in more than one location, but in the example was a calculation module, there is a class with a giant case statement, and that case statement contains a block per insurance type.

The argument given is rather than updating this case statement with another set of calculations you should

  • Put each of those calculations into a separate
    class
  • Setup a factory object which returns the class containing the calculation you will want to perform. (This is where the case statement is located)

The benefits are:

  • There is no chance that the changes you make to the calculation class, will damage the calculation module.

Listkov Substitution Principle

The idea here was inheritance was ‘IS-A’ sort of relationship. The LSP says, this is wrong; it should be ‘IS-SUBSTITUTABLE’. If you cannot substitute then it is probably an error to inherit.

The example they have was a square class and a rectangle class. In theory, you could compose the square class by inheriting from the rectangle class. While (in this example) it might work, however if you think about it, in some code you could substitute a rectangle for a square, but in other places you cannot.
In realistic programing when you start down this avenue, you start adding case statements like if (employeeObj is Manager), then you start adding more and more of these If statements.

Solutions include

  • Don’t inherit
  • Maybe (like in the case of the square/rectangle) you have one object with extra properties like ‘isSquare’.

Interface Segregation Principle

The idea is that interfaces should be basically small. If you find the need to use an interface (which you should feel compelled to) then you should want to implement every function associated with that interface.

The example they gave was an interface provided by Microsoft to accommodate a login page. It had hundreds of functions. Ultimately if you created an object, which inherited that interface, you ended up creating lots of ‘not implemented’ functions, would lead to high maintenance later.
The lesson learned was to develop small functions.
When doing code cleanup. The suggestion is to break those big interfaces into 2 (or more) interfaces. Then in places where you inherit from the bigger interface,
change those classes to inherit from those new interfaces you created. You might find some classes could eliminate blocks of code.

Dependency Inversion Principle