Limit the reasons for a class to change • Classes that only need to change for one reason are easy to change. • Classes that have multiple responsibilities are harder to change. Changing something about one responsibility may break another.
That’s what the Single Responsibility Principle • It’s not “a class should only have one job” • It’s “A software entity should only have one reason to change”
Facilitating change with Interfaces • Other languages allow us to formally define this • Ruby does not • Java for instance has Interfaces. Interfaces define a set of methods that you are going to implement. Objective-C has protocols which is a set of methods and properties
Keep things private • Dynamic languages have implied contracts hidden in the code. When you call a method from another object, you are defining this contract. • Keep this contract as small as possible • Minimum viable method set
Interface Segregation/Single Responsibility as modules • Keep common interface implementations in modules that can be included • eg. Sluggable, Badgeable, PublishesLifeCycleEvents
Keeping objects that share virtual interfaces similar • If you inherit from a class, really inherit all the way. • Don’t explode because something is not set up right • You have a leaky abstraction and you need to take a look at your design
Liskov Substitution Principle • If it looks like a duck and quacks like a duck, but the duck needs batteries, you’ve broken LSP (you have the wrong abstraction) • Preconditions • return or raise if • Postcondition • Catch/Ensure • Try to stay away from new exceptions specific for sub classes. They are hard to catch.
Make it so you can add functionality without modifying the class (or method) • Classic Example • Callbacks/Blocks • Config loops • Dependency Injection • #call • That’s the Open/Close Principle
Thanks! Single Responsilbity A class should have only one reason to change Open/Closed Software entities should be open for extension, but closed for modification Liskov Substition 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 Principle Depend on abstractions, not concretions