Solid Principles C#
SRP - Single Responsibility Principle OCP - Open/Close Principle LSP - Liskov Substitute Principle ISP - Interface Segregation Principle DIP - Dependency Inversion Principle PPD - Pain Driven Development
Single Responsibility Principle | SRP
- Each software module should have one and only one reason to change (A module is a class or function).
- Tight Coupling - binds two or more details together in a way that is difficult to change.
- Loose coupling - offers a modular way to choose which details are involved in a particular operation.
- Separation of concerns - programs should be separated into distinct sections, each addressing a separate concern or set of information that affects the program.
- Using SRP can help simplify writing unit tests.
- Each class should have one responsibility or reason to change.
- Keep your classes small and focussed.
Open/ Close Principle | OCP
- Software entities (classes, modules, functions etc.) should be open for extension, but closed for modification.
- It should be possible to chan ge the behaviour of a method without editing its source code.
- You should think about OCP so that you're not having to continually apply surgery on the same function every time a new requirement arises.
- Why should code be closed to modification!?
- You're then less likely to introduce bugs in code we don't touch or re-deploy. Also less likely to break dependent code. Remember the phrase 'new is glue'
How to predict future changes?
- Start Concrete.
- Modify the code 1 or 2 times.
- By the 3rd modification, consider making the code 'open' to extension.
Typical approaches to OCP:
- Using parameters () and adding arguments.
- Composition and Injection.
Liskov Substitute Principle | LSP
Sub types must be Substitutes for their base types.
Types of Inheritance
- IS-A - (something is-a something else) eg: an eagle IS-A bird.
- HAS-A - (something has-a property) eg: An address HAS-A city.
- LSP states that the IS-A relationship is insufficient and should be replaced with IS-SUBSTITUTABLE-FOR.
- A rectangle has four sides and four right angles.
- A square has four equal sides and four right angles.
- Per geometry a square IS-A rectangle as a square has an invariant (its sides must be equal).
- Rectangle has an invariant its sides are independent. This design breaks rectangles invariants and thus violates LSP.
Fixing LSP violations:
- Follow the "tell, don't ask" Principle.
- Minimise null checks and try to use: C# alternatives, Guard Clauses and null object design pattern.
- Follow ISP and be sure to fully implement interfaces.
Interface Segregation Principle
Clients should not be forced to depend on methods they do not use.
What does interface mean?
- C# interface type/ keyword.
- public (or accessible) interface of a class.
- A types interface in this context is whatever can be accessed by client code working with an instance of that type.
What's a client?
In this context the client is the code that is interacting with an instance of the interface. It's the calling code.
Detecting ISP violations in your code:
- Large interfaces
- NotImplimentedException Code uses just a small subset of a larger interface.
Fixing ISP violations:
- Break up large interfaces into smaller ones.
- To address large interfaces you don't control
- Create a small, cohesive interface.
Dependency Inversion Principle
- High-Level modules should not depend on low-level modules. Both should depend on abstractions.
- Abstractions should not depend on details.
- Details should depend on Abstractions.
Dependencies in C#
- References required to compile.
- References required to run.
- More Abstract
- Business rules
- Process orientated
- Further From input/output (i/o)
- Closer to input/output (i/o)
- "Plumbing code"
- Interacts with specific external systems and hardware.
- File systems
- Web API's
Separation of concerns
- Abstractions in C# are: interfaces and abstract base classes.
- Types you can't instantiate
- Abstractions shouldn't be coupled to details
- Abstractions describe what: send a message | store a customer record
- Details specify how: send an SMTP email over port 25 | serialize customer to JSON and store in txt file.