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
advisormode.
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
- ▶️ All the Little Things Show archive.org snapshot — Sandi Metz, RailsConf 2014; turning a knot of conditionals into small objects, step by step
- 📘 Ruby Science Show archive.org snapshot — thoughtbot, free PDF; a catalog of Rails code smells, each with the refactoring that fixes it
- 📄 Code smells Show archive.org snapshot and the refactoring catalog Show archive.org snapshot — the vocabulary: feature envy, long parameter lists, inappropriate intimacy, and the moves that address them
- 📄 Tell, Don't Ask Show archive.org snapshot — refresher
- 📄 SOLID in Ruby: Single Responsibility Principle Show archive.org snapshot
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
-
📄 Technical debt Show archive.org snapshot — Martin Fowler's definition and the quadrant
-
📄 Are you experiencing technical drift? Show archive.org snapshot — debt that accrues without anyone deciding to take it on
-
📄 Moving fast with high code quality Show archive.org snapshot — how a team keeps debt in check
-
📄 Architecture Antipatterns Show archive.org snapshot — a catalog of structural mistakes that show up in real applications; skim the patterns and think about which ones you have seen
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.