Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SOLID Design Principles in Ruby

SOLID Design Principles in Ruby

Slides from my talk on applying SOLID design principles in Ruby. Originally gave the talk at Nash.rb meetup.

John Bohn

August 07, 2014
Tweet

More Decks by John Bohn

Other Decks in Programming

Transcript

  1. SOLID Design
    Principles in Ruby
    @jjbohn

    View Slide

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

    View Slide

  3. Change Happens
    • Good design is a design that facilitates change

    View Slide

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

    View Slide

  5. 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.

    View Slide

  6. 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”

    View Slide

  7. 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

    View Slide

  8. 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

    View Slide

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

    View Slide

  10. Interface Segregation
    Principle
    • Keep those contracts small

    View Slide

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

    View Slide

  12. 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

    View Slide

  13. 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.

    View Slide

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

    View Slide

  15. 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

    View Slide

  16. 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

    View Slide