OO Design

Post on 16-Jul-2015

288 views 1 download

Tags:

Transcript of OO Design

OO DESIGNby Oleksii Fedorov

OBJECT ORIENTED PROGRAMMING

Most notable features:

Encapsulation (data kept with behaviour and hidden fromclients)Inheritance (subclassing, inheriting all behaviour/data,even private/protected behaviour/data)Polymorphism (ability to substitute instances of one classwith instances of others)

HOW IMPORTANT THESE FEATURES ARE FOROO DESIGN?

Imagine, that given 100 points you want to distribute thembetween these 3 features, and each number will represent

an importance of corresponding feature.

Encapsulation Polymorphism Inheritance

80 40 -20

Warning: this is my personal opinion

80 + 40 - 20 = 100 :)

INHERITANCE INCREASES COUPLINGSubclass usually depends on some data or/and behaviour of

its superclass. Even worse: usually this is not publicbehaviour/data.

BUT HOW DOES ONE GO WITHOUTINHERITANCE?

COMPOSITION AND DELEGATION

COUPLING

WHY COUPLING IS BAD?

Imagine you need to change behaviour of class X.

You will have to change any other piece of code base, thatdirectly depends on this behaviour of class X.

More coupling you have, more changes will have to takeplace, and probably, in totally unrelated parts of codebase.

Exponentially increases time required for changeInvites bugs

DEPENDENCY

HOW DOES ONE DEAL WITH IT?

DEPENDENCY INVERSION AND DEPENDENCYINJECTION

class Answer  def rating    RatingCalculator.new.rating_for(comments, upvotes, downvotes)  endend

AND WHAT THE PROBLEM WITH THIS CODE?

DEPENDENCY!

class Answer  def initialize(rating_calculator)    @rating_calculator = rating_calculator  end

  def rating    @rating_calculator.rating_for(comments, upvotes, downvotes)  endend

NOW YOU CAN HAVE MULTIPLE RATINGCALCULATOR SERVICES AND A/B TEST THEM

EASILY

COUPLE TO ABSTRACT INTERFACES INSTEADOF REFERENCING FOREIGN

CLASS/MODULE/PACKAGE OF YOUR SYSTEM

TEST DRIVEN DEVELOPMENT

HOW IS IT RELATED TO OO DESIGN?

PROVIDES SHORT FEEDBACK LOOP ON YOURDESIGN

If you have troubles writing test - your design is wrongIf you don't like how your test look like - your design iswrongIf you have troubles making test green - your design iswrong

UNIT TESTS AND INTEGRATION TESTS

INTEGRATION TESTS ARE SCAM!Very slow => bad feedback loopExponential count of paths to test

UNIT TESTS JUST DOESN'T WORK. ARETHEY?

Testing in isolation = providing fake objects and/or mocksfor all your dependencies

Mocks and fake objects can make your unit test green, but infact the code is broken, because one of the dependencies

has changed its behaviour or even public interface

CUT YOUR SYSTEM AT VALUE BOUNDARIES!Instead of method call boundaries.

ACTOR MODEL

class RatingCalculator  def rating_for(comments, upvotes, downvotes)    # .. calculate rating somehow ..  endend

actor RatingCalculator  comments, upvotes, downvotes, outbox = inbox.fetch  # .. calculate rating somehow ..  outbox.send(rating)end

ALMOST ALWAYS HAS EXACTLY ONE SINGLERESPONSIBILITY

Since it receives message on inbox and doesn't really havemuch space to have multiple responsibilities (and methods)

EASY TO UNIT TEST WITHOUT FAKE OBJECTSAND MOCKS

# creating actor, but not starting itrating_actor = RatingCalculator.new

# dependency injection of rating actoranswer_actor = Answer.new(answer_id, rating_actor)answer_actor.start

render_actor = Render.new(answer_actor)render_actor.runexpect(rating_actor.inbox)  .to include([comments, upvotes, downvotes, outbox])

# fake response from rating actoroutbox.send(3.5)expect(render_actor).to render_rating(3.5)

WHEN THE CODE IS DONE?

It works!

It works!It is readable (future me will not curse me for writing thiscode)

It works!It is readable (future me will not curse me for writing thiscode)It has no duplicationAnd it is as short as possible (while maintaining all of theabove)

CODE COMMENTS

BASICALLY A CODE SMELL

If code needs comment:

It is not readableIt fails to communicate intent

TO SUM IT UP

Inheritance is good only in very rare casesCoupling and dependencies are not your friends, takethem under control with dependency inversion &injectionTDD as a shortest feedback cycle for your OO designWrite code in such way, that you would thank yourself forthat in the future

THAT IS NOT ALL THERE ABOUT OO DESIGNI recommend reading the book "Pragmatic Programmer:

From Journeyman to Master", it is very good one and has alot of references to other good resources

THANKSQ & A