jargon

Subjects·10 topics·201 terms

Design patterns

Objects, SOLID, the Gang of Four catalogue, persistence and domain modelling, functional idioms and the named anti-patterns.

Start with these 58, in order

Objects, SOLID, the Gang of Four catalogue, persistence and domain modelling, and the named ways all of it goes wrong.

Read in order · tick what you already know

  1. 01

    one class is four thousand lines and every feature branch touches it.

    God objectArchitecture

  2. 02

    there is a 3 in the middle of the expression and nobody left a note saying which three that is.

    Magic number

  3. 03

    two tests passed on their own and failed together, because the thing they both reached for kept state between them.

    Singleton

  4. 04

    there is an interface with one implementation and a config flag that has never been anything but its default.

    Premature abstraction

  5. 05

    adding one field meant small edits in eleven files, and the review caught the two you missed.

    Shotgun surgery

  6. 06

    understanding one method meant opening five files up and down the hierarchy, and then going back up again.

    Yo-yo problem

  7. 07

    someone described a solution in four words and everyone in the room pictured roughly the same code.

    Design pattern

  8. 08

    somebody says a pattern is 'GoF' and means it came from the 1994 book rather than from a framework.

    Gang of Four

  9. 09

    another team reached into the field directly, and now you cannot rename it without breaking them.

    EncapsulationArchitecture

  10. 10

    the same call site does three different things depending on what was passed in, and there is no branch anywhere.

    Polymorphism

  11. 11

    you got twenty methods you never asked for along with the one you wanted, and you cannot give any of them back.

    Inheritance

  12. 12

    you said it out loud — a Stack is a List — and it sounded fine right up until someone called insert in the middle of it.

    Is-a vs has-a

  13. 13

    the subclass needed one method overridden and inherited four others it never wanted and cannot remove.

    Composition over inheritanceArchitecture

  14. 14

    the method body is one line that calls the same method on a field, and that is the whole class's job for that method.

    Delegation

  15. 15

    someone rejected the pull request citing a five-letter acronym, and only two of the five letters were actually about the problem.

    SOLID

  16. 16

    two teams keep editing the same class for two entirely unrelated reasons and keep colliding.

    Single responsibilityArchitecture

  17. 17

    adding the fourth payment method meant editing the same switch statement for the fourth time.

    Open–closed principle

  18. 18

    the subclass threw on a method the parent promised, and every caller written against the parent was suddenly wrong.

    Liskov substitution principle

  19. 19

    you implemented an eleven-method interface to get at one of them and threw not-implemented from the other ten.

    Interface segregation principle

  20. 20

    the business rules import the Postgres driver, so testing a discount calculation needs a database.

    Dependency inversionArchitecture

  21. 21

    you wrote order.getCustomer().getAddress().getPostcode() and a change three objects away broke your line.

    Law of DemeterArchitecture

  22. 22

    the class asks for what it needs in its constructor and never goes looking, so a test can hand it anything.

    Dependency injection

  23. 23

    you stopped writing the loop and started writing the thing the framework calls, and you no longer decide when.

    Inversion of control

  24. 24

    the class asks a global object for what it needs mid-method, so its dependencies are invisible until it runs.

    Service locator

  25. 25

    the base class does the work and calls a method for the object it needs, and each subclass answers that with a different class.

    Factory method

  26. 26

    you swap one object at startup and the whole family of things it creates changes together, consistently.

    Abstract factory

  27. 27

    you set five things by name across five lines and call build, and the object does not exist until the last one.

    Builder pattern

  28. 28

    the object holds another object and forwards most calls to it, and which pattern that is depends entirely on why.

    Wrapper

  29. 29

    the library's method was called differently and returned the wrong shape, so you wrote a class that speaks both.

    Adapter pattern

  30. 30

    you replaced eleven calls across four classes with one method, and callers stopped needing to know the order.

    Facade pattern

  31. 31

    you wrapped the same interface in retries, then logging, then caching, and the caller still sees one thing.

    Decorator pattern

  32. 32

    the object looks and behaves exactly like the real one, and its whole job is deciding whether the call gets through.

    Proxy pattern

  33. 33

    the class takes the algorithm as a constructor argument, and choosing a different one is a different argument.

    Strategy pattern

  34. 34

    the object's behaviour changed after a call and nothing branched — it had swapped the object it was delegating to.

    State pattern

  35. 35

    the base class runs the five steps in order and leaves two of them abstract for you to write.

    Template method

  36. 36

    you changed one field and four other things updated, and finding out which four meant reading a subscription list.

    Observer pattern

  37. 37

    the request became an object with an execute method, so you could put it in a queue, log it and undo it.

    Command pattern

  38. 38

    you walked the collection without knowing whether it was an array, a tree or a paged remote call.

    Iterator pattern

  39. 39

    you added a new operation over the whole tree by writing one class, and did not touch any of the node types.

    Visitor pattern

  40. 40

    instead of returning null you returned something that implements the interface and does nothing, and the null checks disappeared.

    Null object

  41. 41

    the invalid cases return in the first four lines, and the rest of the method is not indented at all.

    Guard clause

  42. 42

    two of them with the same contents are interchangeable, so you never update one — you replace it.

    Value object

  43. 43

    two of them with identical fields are still different things, because the thing that makes them the same is the id.

    Entity

  44. 44

    you can change these five objects together in one transaction, and anything outside them has to wait its turn.

    Aggregate

  45. 45

    the objects have only fields and accessors, and every rule about them lives in a class ending in Service.

    Anaemic domain model

  46. 46

    the code asks for the customer as if from an in-memory collection, and where it actually came from is somewhere else.

    Repository pattern

  47. 47

    the object has a save method on it, so the thing that models an order also knows the table it lives in.

    Active record

  48. 48

    the domain object has no idea a database exists, and a separate class knows which column each field came from.

    Data mapper

  49. 49

    the browser posted to a controller, which changed the model and picked a view, and the view read the model itself.

    Model-view-controller

  50. 50

    the same use case runs from an HTTP handler, a message consumer and a test, and none of them is the primary one.

    Hexagonal architecture

  51. 51

    entities, then use cases, then adapters, then frameworks — and nothing in an inner circle names anything outside it.

    Clean architecture

  52. 52

    you called it twice with the same arguments, got the same answer, and nothing anywhere else changed.

    Pure function

  53. 53

    nothing that was handed out can be changed, so you stopped copying defensively and stopped worrying about who else holds it.

    Immutability

  54. 54

    the function's argument is another function, and what it actually does depends entirely on what you passed.

    Higher-order function

  55. 55

    the test passed alone and failed in the suite, and the difference was something another test had left behind.

    Global mutable state

  56. 56

    two modules import each other, and which one is initialised first decides whether it works.

    Circular dependency

  57. 57

    money is a decimal, the email is a string, and the validation for both is repeated in nine call sites.

    Primitive obsession

  58. 58

    the method calls five getters on another object and one on itself, so it belongs on that other object.

    Feature envy

All of design patterns

Every term in this subject, 201 of them, grouped into 10 topics. Each topic is a track of its own.

Before any pattern there is a smaller question: what is one object allowed to know about another. Almost every named pattern is an answer to it, and almost every argument in a code review is really about it.

Making things

02 · 16 terms

Construction looks like the boring half until the constructor has nine arguments, the object is half-built for a moment, or two tests fight over the one instance. These are the patterns for deciding what gets built, by whom, and when.

Somewhere a decision gets made about which concrete thing your code actually gets, and the whole testability of a codebase turns on where that somewhere is. This is the vocabulary of moving it out of the class and into one place.

Four of these patterns are the same shape — an object that holds another object and forwards to it — and they are the four people mix up most. The difference is never the diagram; it is why the wrapper exists.

These are the patterns about the flow of control rather than the shape of the objects: swapping an algorithm, reacting to a change, turning a request into a thing you can queue, undo or log.

Objects have identity, references and behaviour; rows have keys, foreign keys and no behaviour at all. Every pattern here is a different position on how much of that gap to hide, and what each choice costs you later.

Modelling the domain

07 · 16 terms

The words a team uses when it stops arguing about frameworks and starts arguing about what an order actually is. These are the pieces a domain model is built from and the failure it decays into.

Zoomed all the way out, an application is a small number of regions and a rule about which way the arrows between them may point. These are the named shapes, and the differences between the ones people use interchangeably.

Most of these arrived in ordinary object-oriented codebases without the theory attached, and they are now said in reviews by people who have never written a line of Haskell. This is what they mean when they are.

A pattern gives a good arrangement a name so it can be asked for. An anti-pattern gives a bad one a name so it can be pointed at without the argument starting from scratch, which is most of what these are for.