solid - ood principles

20

Click here to load reader

Upload: bankfacil

Post on 28-Jul-2015

176 views

Category:

Engineering


3 download

TRANSCRIPT

Page 1: Solid - OOD Principles

SOLID

SOLID

Barbara Barbosa - @bahbbc

BankFacil - @BankFacilDev

19 de maio de 2015

Page 2: Solid - OOD Principles

SOLID

SOLID - OOD Principles

S - Single-responsibility

O - Open-closed

L - Liskov substitution

I - Interface segregation

D - Dependency inversion

Attention!

These are principles, not laws!!!

Page 3: Solid - OOD Principles

SOLID

Single-responsibility Principle - SRP

There should never be more than one reason for a class to change.

class AuthenticatesUser

def authenticate(email, password)

if matches?(email, password)

do_some_authentication

else

raise NotAllowedError

end

end

private

def matches?(email, password)

user = find_from_db(:user, email)

user.encrypted_password == encrypt(password)

end

end

Page 4: Solid - OOD Principles

SOLID

Single-responsibility Principle - SRP

Refactor extract class for the rescue! o/

class AuthenticatesUser

def authenticate(email, password)

if MatchesPasswords.new(email, password).matches?

do_some_authentication

else

raise NotAllowedError

end

end

end

Page 5: Solid - OOD Principles

SOLID

Single-responsibility Principle - SRP

class MatchesPasswords

def initialize(email, password)

@email = email

@password = password

end

def matches?

user = find_from_db(:user, @email)

user.encrypted_password == encrypt(@password)

end

end

Page 6: Solid - OOD Principles

SOLID

Single-responsibility Principle - SRP

Just because you can, doesn’t mean you should!Tips!

Split big classes

Avoid GOD classes

Write straightforward comments

Page 7: Solid - OOD Principles

SOLID

Open-closed Principle - OCP

Objects or entities should be open for extension, but closed formodification.

class Report

def body

generate_reporty_stuff

end

def print

body.to_json

end

end

Page 8: Solid - OOD Principles

SOLID

Open-closed Principle - OCP

Using some Dependency Injection here

class Report

def body

generate_reporty_stuff

end

def print(formatter: JSONFormatter.new)

formatter.format body

end

end

Now just do this:

report = Report.new

report.print(formatter: XMLFormatter.new)

Page 9: Solid - OOD Principles

SOLID

Open-closed Principle - OCP

Tips!

Make all member variables private

Really think about global variables...

Avoid setters

Page 10: Solid - OOD Principles

SOLID

Liskov substitution - LSP

Subtypes must be substitutable for their base types.

class Animal

def walk

do_some_walkin

end

end

class Cat < Animal

def run

run_like_a_cat

end

end

Page 11: Solid - OOD Principles

SOLID

Liskov substitution - LSP

So, they must have the same interface. Since ruby does not haveabstract methods, we can do it like so:

class Animal

def walk

do_some_walkin

end

def run

raise NotImplementedError

end

end

class Cat < Animal

def run

run_like_a_cat

end

end

Page 12: Solid - OOD Principles

SOLID

Interface Segregation Principle - ISP

A client should never be forced to implement an interface that itdoesn’t use or clients shouldn’t be forced to depend on methodsthey do not use.

class Car

def open

end

def start_engine

end

def change_engine

end

end

Page 13: Solid - OOD Principles

SOLID

Interface Segregation Principle - ISP

class Driver

def drive

@car.open

@car.start_engine

end

end

class Mechanic

def do_stuff

@car.change_engine

end

end

Page 14: Solid - OOD Principles

SOLID

Interface Segregation Principle - ISP

In other words, you should not have to implement methods thatyou don’t use.

class Car

def open

end

def start_engine

end

end

class CarInternals

def change_engine

end

end

Page 15: Solid - OOD Principles

SOLID

Interface Segregation Principle - ISP

class Driver

def drive

@car.open

@car.start_engine

end

end

class Mechanic

def do_stuff

@car_internals.change_engine

end

end

Page 16: Solid - OOD Principles

SOLID

Dependecy Invertion Principle - DIP

Abstractions should not depend upon details. Details shoulddepend upon abstractions.

class Report

def body

generate_reporty_stuff

end

def print

JSONFormatter.new.format(body)

end

end

class JSONFormatter

def format(body)

...

end

end

Page 17: Solid - OOD Principles

SOLID

Dependecy Invertion Principle - DIP

class Report

def body

generate_reporty_stuff

end

def print(formatter: JSONFormatter.new)

formatter.format body

end

end

Page 18: Solid - OOD Principles

SOLID

Dependecy Invertion Principle - DIP

Attention!

Dependecy Invertion isn‘t the same as Dependency Injection!

Level of abstraction vs how an object acquires a dependency

Page 19: Solid - OOD Principles

SOLID

Conclusion

The principles are good to make better decisions;

Avoiding tight coupling is the key;

SOLID is not that hard =)

Page 20: Solid - OOD Principles

SOLID

References

SOLID Principles with Ruby -https://www.groupbuddies.com/posts/19-solid-principles-in-ruby

From STUPID to SOLID code -http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code/

SOLID the first 5 principles of OOD - https://scotch.io/bar-talk/s-o-l-i-d-the-first-five-principles-of-object-oriented-design