More Software design [2d]

Building on Software design basics, this lesson covers more principles and code smells, technical debt, and architecture antipatterns, using real repos to find examples.

Important

Work on this lesson in advisor mode.

Learning goals

  • You can explain what a code smell is and recognize the common ones in Ruby code, e.g. feature envy, objects reaching deep into other objects, classes with several responsibilities.
  • You can apply the design principles you know — single responsibility, Law of Demeter, Tell Don't Ask — to real code and propose a concrete refactoring.
  • You can explain what technical debt and technical drift are, how they arise, and how a team keeps them in check.
  • You can find examples of debt and drift in a real repository and explain why they happened.
  • You can recognize code that ignores module boundaries — logic for one concept scattered across models, controllers, views and helpers — and pull it back into one place. This is the most common flaw in agent-generated code.

Resources

Read what's new to you, skim what's familiar, skip what you already master. Stop when you can meet the learning goals.

Your agent can also generate an overview, a tutorial or an explanation for anything here, tailored to what you already know. Just ask.

Code smells and refactoring

Module boundaries

  • 📄 Rails with protected modules Show archive.org snapshot — namespaces with a small public API and private_constant: how to keep one concept in one place
  • 📘 Practical Object-Oriented Design in Ruby (Sandi Metz, in our library) — chapter 3 "Managing Dependencies" and chapter 4 "Creating Flexible Interfaces"

Technical debt

Exercises

Find the smells

Look at the repos for Cards and your MovieDB. Find examples where code could be improved with the principles and smells above, and propose a concrete refactoring for each.

Find the debt

Look at the repo for your MovieDB and at the repo for Cards:

  • Can you find examples of technical debt or drift?
  • Why did it happen?

Find the scattered concept

Take one concept in Cards that is truly scattered — the card search — and list every file that knows about it. Where does logic for that concept live in models, controllers, views and helpers? Sketch where it should live, and what a single module for it would look like.

Henning Koch