Nicer to work with.
Less likely to have bugs.
Most importantly: easy to change.
Don’t add something because it might come in handy!
Outside-in TDD helps.
Regexps are the same.
What if you find a bug? What if they’re miles apart? Can you guarantee you’ll change both?
Extract duplicate code so each piece of knowledge is represented in one place.
Give it a name that makes it clear what it does.
You could also argue that there’s still duplication: only the field changes.
Is this the same? No!
Different concepts – incidental duplication.
If you extracted the regexp and order ID format changed, you’d break EIN validation.
Three responsibilities.
If one changes, need to modify the class. Potential to break stuff.
Employee class is now only responsible for persistence.
Introduce separate classes for other responsibilities.
Sounds crazy, right?
Currently we want to log an event whenever an employee is added.
What if we also wanted to send an email to the payroll team, or notify some other system? We’s need to modify this class.
Same issue as before – changing a class risks introducing bugs.
Allow registration of any number of listeners…
…then notify them all.
No need to change the class.
Square is a subclass of Rectangle.
Seems legit – a square is a rectangle, after all.
No complaints from the compiler, because Square is a valid Rectangle.
Hmm.
Turns out in this case it’s not valid for Square to be a subclass of Rectangle.
In this specific case, if the classes were immutable there wouldn’t be a problem.
Do we really want to risk code related to sending newsletters accidentally giving someone a payrise?
A bit contrived, but if we expose all an object’s methods everywhere, it’s easy for functionality to creep into the wrong places.
Narrow interfaces.
Employee now implements both.
Methods can be restricted to just the relevant interface.
Not going to go into detail about exactly what this means, but just a simple example.
EmployeeRegistry (high level) depends on Database (low level and specific).
What if we want to change database, or use a fake for testing?
DbConnection is an abstraction.
We now inject the connection into the constructor, so it can be replaced with a different implementation without changing the registry class.
Intent: each piece of the system should do one thing only, and make it clear what that is.
Duplication: concepts as well as actual chunks of code.
Ordered, highest priority first.
Good names better than comments.
Originally for Ruby.
Maybe add a few lines for Java because it’s more verbose.