####Chapter 1 - Object Oriented Design
The purpose of design is to allow you to do design later, and it's primary goal is to reduce the cost of change.
- Single Responsibility Principle: a class should have only a single responsibility
- Open-Closed Principle: Software entities should be open for extension, but closed for modification (inherit instead of modifying existing classes).
- Liskov Substitution: Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
- Interface Segregation: Many client-specific interfaces are better than one general-purpose interface.
- Dependency Inversion: Depend upon Abstractions. Do not depend upon concretions. See Dependency Injection
Other principles include:
- Do Not Repeat Yourself: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
- Law of Demeter: A given object should assume as little as possible about the structure or properties of anything else.
A class should do the smallest possible useful thing.
Applications that are easy to change consist of classes that are easy to resue.
How can you determine if the
Gearclass contains behavior that belongs somewhere else? One way is to pretend that it's sentient and to interrogate it. If you rephrase every one of it's methods as a question, asking the question ought to make sense. For example, asking "Gear, what is your ratio?" seems perfectly reasonable..."Gear, what is your tire size?" is just downright ridiculous.
Depend On Behavior, Not Data
Hide instance variables. [Code example]
Hide data structures. [Code example]
An object depends on another object if, when one object changes, the other might be forced to change in turn.
Recognizing Dependencies
An object has a dependency when it knows:
- The name of another class
- The name of a message that it intends to send to someone other than
self(methods on other objects). - The arguments that a message requires.
- The order of those arguments.
Your design challenge is to manage dependencies so that each class has the fewest possible; a class should know just enough to do it's job and not one thing more.
The more one class knows about another, the more tightly it is coupled.
Test-to-code over-coupling has the same consequence as code-to-code over-coupling.
Factory: an object whose purpose is to create other objects.
Depend on things that change less often than you do.
- Some classes are more likely than others to have changes in requirements
- Concrete classes are more likely to change than abstract classes
- Changing a class that has many dependents will result in widespread consequences
Abstraction in Ruby = duck typing; depending on an interface (objects will respond to methods) rather than a concrete class implementation.
Domain objects are easy to find but they are not at the design center of your application. They are a trap for the unwary. If you fixate on domain objects you will tend to coerce behavior into them. Design experts notice domain objects without concentrating on them; they focus not on these objects but on the messages that pass between them.
However I will only update this page once,