Chapter 12 Flashcards — Emergence
flashcards clean-code emergence simple-design dry refactoring
What are Kent Beck’s Four Rules of Simple Design, in priority order?
?
- Runs all the tests — the system is verifiable; 2. No duplication — every piece of knowledge has one representation; 3. Expresses the intent of the programmer — code communicates clearly; 4. Minimizes the number of classes and methods — no unnecessary abstraction.
What does “emergent design” mean in the context of Clean Code?
?
A good overall design does not have to be fully planned upfront. When you consistently follow the four rules of simple design (tests, no duplication, expressiveness, minimalism), a clean architecture emerges naturally from the discipline — without requiring a big upfront design phase.
Why does Rule 1 (runs all the tests) improve design?
?
Writing tests creates pressure toward better structure: classes that are hard to test are almost always poorly designed. Test pressure pushes toward small focused classes, DI for seams, low coupling, and SRP. A testable class is almost always a well-designed class.
What is the relationship between testability and the Single Responsibility Principle?
?
A class that does too many things is hard to test: its setup requires building many collaborators, and a test failure could be caused by any of its responsibilities. SRP — doing one thing — produces classes with minimal setup and obvious failure points. Testability pressure naturally enforces SRP.
What is DRY, and why is duplication the primary enemy of a well-designed system?
?
DRY (Don’t Repeat Yourself): every piece of knowledge has one authoritative representation. Duplication is the primary enemy because every copy is a future inconsistency: a bug fix must be applied in N places; a behavior change must be applied in N places. Each copy drifts independently over time.
What is the difference between code-level duplication and design-level duplication?
?
Code-level: identical or near-identical blocks of code (e.g., the same validation loop in three service classes). Design-level: the same sequence of steps repeated across classes, with only one or two steps varying (e.g., fetch → validate → format → send, where only “format” differs). Template Method solves design-level duplication.
What is the Template Method pattern and which type of duplication does it eliminate?
?
Template Method defines a skeleton algorithm in an abstract base class with the invariant steps implemented there and the varying steps declared as abstract methods for subclasses to fill in. It eliminates design-level duplication — when multiple classes share the same sequence of operations but differ in one or two steps.
In Template Method, what is a “hook” method?
?
A hook is an abstract (or optionally overridable) method that represents the varying step. Subclasses override only the hook; the rest of the algorithm — defined in the template method — stays in the base class. The template method is typically marked final (Java) or non-virtual (C++) to prevent subclasses from changing the sequence.
What is “coincidental similarity” and why should you NOT eliminate it with DRY?
?
Two pieces of code that happen to produce the same result for different conceptual reasons. If the business reason for changing them could ever differ, they represent separate concepts. Merging them creates hidden coupling — a change to one concept unintentionally changes the other. DRY applies to the same concept, not coincidentally similar code.
What is the most important technique for expressing programmer intent?
?
Naming — giving classes, methods, and variables names that express their business purpose rather than their implementation. isEligibleForFullBenefits() expresses a business rule; the equivalent inline condition hides it. A reader understands the call site without reading the implementation.
How does extracting a condition into a well-named method improve expressiveness?
?
It moves the business rule to the place where it is used (the call site reads as a sentence: if (employee.isEligibleForFullBenefits())) and isolates the implementation detail inside the method. Future readers understand the intent at the call site without needing to understand the implementation — unless they specifically need to.
How do standard design pattern names contribute to expressiveness?
?
Pattern names carry shared meaning beyond their code. OrderCommand tells any developer who knows the Command pattern: this encapsulates a request, has an execute() method, may support undo. Pattern names are a shared vocabulary that reduces explanation overhead and sets accurate expectations instantly.
Name four design patterns and the intent each communicates through its name.
?
Command — encapsulates a request as an object; supports queuing and undo. Visitor — separates an operation from the object structure it operates on. Decorator — adds behavior to an object without changing its class. Template Method — defines a sequence skeleton in a base class; subclasses fill in the varying step.
Why are well-written unit tests considered one of the best forms of documentation?
?
Tests are documentation that cannot go stale — if the behavior changes without updating the test, the test fails. A good test name reads as a specification: employeeWithMoreThan40HoursAndOneYearTenureIsEligibleForFullBenefits. Tests show precise inputs, expected outputs, and edge cases the author considered.
What is Rule 4 (Minimizes classes and methods) counterbalancing?
?
Rules 1-3 can be taken too far: obsessive test coverage of trivial code, extracting methods for two-line repetitions, creating patterns for every concept. Rule 4 is the counter-weight: keep the system as small as possible while still satisfying rules 1-3. Every class and method must justify its existence.
In what order do Kent Beck’s four rules take priority, and what does that ordering imply?
?
Priority order: tests → no duplication → expressiveness → minimalism. The ordering means: tests always win; a test that requires extracting a class beats minimalism. Eliminating duplication beats expressiveness (a concise but duplicated expression should be extracted). Expressiveness beats minimalism (a clear name beats a compact one).
What is the signal that you should apply the Template Method pattern?
?
When you see multiple classes with the same sequence of method calls (fetch → validate → process → notify), where only one or two steps differ, and you find yourself copy-pasting the shared steps. Template Method puts the shared steps in one place and makes the varying step explicit as an abstract method.
What does “tests enable refactoring” mean?
?
A test suite is the safety net that proves behavior is preserved after a change. Without tests, refactoring (improving structure without changing behavior) is guesswork — you cannot verify you did not introduce a regression. With tests, you can aggressively improve code structure because any breakage is immediately visible.
Why should test names read like specifications?
?
A test named test1() tells you nothing when it fails — you must read the implementation. A test named newHireIsNotEligibleForFullBenefitsRegardlessOfHours tells you exactly what scenario failed and what the expected behavior is. Test names are executable documentation of the system’s business rules.
What is the key question to ask when deciding whether to extract a new class or method?
?
“Can I justify this extraction to a colleague?” — is there duplication being eliminated, a concept being named, or complexity being isolated? If you cannot articulate why the extraction exists, it probably should not. The bar is: does this extraction make the code clearer, simpler, or more changeable than it was before?
Give an example of over-abstraction that violates Rule 4.
?
Creating an EmployeeNameFormatter interface, a FullNameFormatter implementation, and an EmployeeNameFormatterFactory — three classes — to do firstName + " " + lastName. A single fullName() method is sufficient. The abstraction adds navigation burden and code to maintain without delivering testability or extensiveness.
How does DI (Dependency Injection) enable Rule 1 (runs all tests)?
?
DI allows tests to substitute fake implementations for real collaborators (database, email server, payment API). Without DI, a class that constructs its own dependencies (new SmtpEmailService(...)) drags real infrastructure into every test. DI is the structural mechanism that makes unit testing (isolated, fast, hermetic) possible.
What is a “seam” in the context of testability?
?
A seam is a place where you can alter behavior without editing the code itself — a point where a fake can be substituted for a real implementation. Constructor injection creates a seam (pass in a fake). Interface-based dependencies create seams (implement the interface differently in tests). No seams → untestable code.
What is the minimum viable test suite per Rule 1?
?
Every public behavior of every class should have at least one test. The test does not need to cover every code path exhaustively, but it must verify the primary contract of the class. Rule 1 says the system must be verifiable — you need enough tests that you can refactor with confidence, not achieve 100% coverage of trivial getters.
Why is “expressive code” Rule 3 and not Rule 1 or 2?
?
Rules 1 and 2 are objective: a test either runs or it does not; code either has duplication or it does not. Expressiveness is more subjective and somewhat dependent on rules 1 and 2 being met first — tests give you the confidence to rename and restructure, and eliminating duplication often makes naming opportunities more visible. But expressiveness still beats minimalism (Rule 4).
Total Cards: 25
Review Time: ~20 minutes
Priority: HIGH
Last Updated: 2026-04-14