Slide 1

Slide 1 text

SOLID Design Principles in Ruby @jjbohn

Slide 2

Slide 2 text

What is good design? • Easy to reason about • Easy to change

Slide 3

Slide 3 text

Change Happens • Good design is a design that facilitates change

Slide 4

Slide 4 text

How do we facilitate change? • Make it easy to swap one type of object for another • Give objects a common interface to work from

Slide 5

Slide 5 text

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.

Slide 6

Slide 6 text

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”

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Dependency Inversion Principle • Depend upon Abstractions. Do not depend upon concretions. • Write code that relies on quacking, not ducks.

Slide 10

Slide 10 text

Interface Segregation Principle • Keep those contracts small

Slide 11

Slide 11 text

Interface Segregation/Single Responsibility as modules • Keep common interface implementations in modules that can be included • eg. Sluggable, Badgeable, PublishesLifeCycleEvents

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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.

Slide 14

Slide 14 text

Another Way - Allow Substitution via Optional Conversion • Tell the object to convert itself to what you are looking for

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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