Software design and clean code

Stage 2 of 10 · 7 lessons · ~3 weeks

SOLID with before and after code

Learn the five SOLID principles as questions to ask of a design, see each one as a before and after refactoring in your language, and learn dependency injection, the technique that makes them practical.

Start: Single responsibility

Lessons· one lesson for each topic, in this order

  1. 1Single responsibility
  2. 2Open for extension, closed for modification
  3. 3Liskov substitution
  4. 4Interface segregation
  5. 5Dependency inversion
  6. 6Dependency injection in practice
  7. 7DRY, KISS and YAGNI: the counterweights

Do this

  • Write a one-sentence description of every class in one project and split any that need "and".
  • Replace one growing switch with an interface or a function parameter.
  • Find one subclass that throws "not supported" and redesign it.
  • Move one class from creating its dependencies to receiving them in the constructor.
  • Write a unit test for that class using a hand-written fake.
  • Undo one abstraction you added that has a single implementation and no expected change.

Start with· follow one of these

  • CoursePaid
    Grokking SOLID Design Principles

    Design Gurus · Beginner · $50 one-time

    One chapter per principle, each with the violation and the refactoring that fixes it

  • CourseFree
    MIT 6.102: Software Construction

    MIT · Intermediate

    Free: the Specifications and Interfaces and Subtyping readings explain substitution as contracts

Keep handy

  • Search it for dependency injection and inversion of control: the articles that named the ideas

Also worth your time

Before moving on: A small before and after repository: one deliberately messy module, such as order checkout, refactored in separate commits for each SOLID principle, with unit tests using fakes and a short README explaining which principle each commit applies and why.

Tauseef's advice
Do not memorise SOLID as five definitions. For each one, learn the smell it prevents: a class that changes for many reasons, a switch that grows, a subclass that throws, a fat interface, a class that news up its database. When you can spot the smell, the principle is doing its job.

Mark this stage as not done?