35
Patterns, Antipatterns, and SOLID (ESaaS §11.1) Armando Fox © 2013 Armando Fox & David Patterson, all rights reserved

Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

  • Upload
    others

  • View
    7

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Patterns, Antipatterns, and SOLID

(ESaaS §11.1)!Armando Fox"

© 2013 Armando Fox & David Patterson, all rights reserved

Page 2: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Design Patterns Promote Reuse"

“A pattern describes a problem that occurs often, along with a tried solution to the problem” - Christopher Alexander, 1977!

•  Christopher Alexander’s 253 (civil) architectural patterns range from the creation of cities (2. distribution of towns) to particular building problems (232. roof cap) "

•  A pattern language is an organized way of tackling an architectural problem using patterns "

•  Separate the things that change from those that stay the same!

Page 3: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Kinds of Patterns in Software"•  Architectural (“macroscale”) patterns"

–  Model-view-controller"–  Pipe & Filter (e.g. compiler, Unix pipeline)"–  Event-based (e.g. interactive game)"–  Layering (e.g. SaaS technology stack)"

•  Computation patterns"–  Fast Fourier transform"–  Structured & unstructured grids"–  Dense linear algebra"–  Sparse linear algebra"

•  GoF (Gang of Four) Patterns: structural, creational, behavior!

Page 4: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

The Gang of Four (GoF)"•  23 structural design patterns"•  description of communicating

objects & classes"–  captures common (and

successful) solution to a category of related problem instances"

–  can be customized to solve a specific (new) problem in that category"

•  Pattern ≠"–  individual classes or libraries (list, hash, ...)"–  full design—more like a blueprint for a design"

Page 5: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

The GoF Pattern Zoo"1.  Factory"2.  Abstract factory"3.  Builder"4.  Prototype"5.  Singleton/Null obj"6.  Adapter"7.  Composite"8.  Proxy"9.  Bridge"10. Flyweight"11. Façade"12. Decorator"

13. Observer"14. Mediator"15. Chain of responsibility"16. Command"17.  Interpreter"18. Iterator"19. Memento (memoization)"20. State"21. Strategy"22. Template"23. Visitor"

Creation"

Structural"

Behavioral"

Page 6: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Meta-Patterns"

Separate out the things that change from those that stay the same"

1.  Program to an Interface, not Implementation"

2.  Prefer composition & delegation over Inheritance"–  delegation is about interface sharing,

inheritance is about implementation sharing"

Page 7: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Antipattern"

•  Code that looks like it should probably follow some design pattern, but doesn’t"

•  Often result of accumulated technical debt"•  Symptoms:"

– Viscosity (easier to do hack than Right Thing)"–  Immobility (can’t DRY out functionality)"– Needless repetition (comes from immobility)"– Needless complexity from generality"

Page 8: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

SOLID OOP principles(Robert C. Martin, co-author of Agile Manifesto)"

Motivation: minimize cost of change "•  Single Responsibility principle"•  Open/Closed principle"•  Liskov substitution principle"•  Injection of dependencies "

–  traditionally, Interface Segregation principle"

• Demeter principle"

Page 9: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Refactoring & Design Patterns"Methods within a class! Relationships among classes!Code smells" Design smells"Many catalogs of code smells & refactorings"

Many catalogs of design smells & design patterns"

Some refactorings are superfluous in Ruby"

Some design patterns are superfluous in Ruby"

Metrics: ABC & Cyclomatic Complexity"

Metrics: Lack of Cohesion of Methods (LCOM)"

Refactor by extracting methods and moving around code within a class"

Refactor by extracting classes and moving code between classes"

SOFA: methods are Short, do One thing, have Few arguments, single level of Abstraction"

SOLID: Single responsibility per class, Open/closed principle, Liskov substitutability, Injection of dependencies, Demeter principle"

Page 10: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Software that uses more design patterns isn’t necessarily better.

Well-designed software can evolve to the point where patterns become antipatterns.

Trying to apply design patterns too early can be just as bad as applying them too late.

Most design patterns are specific to a particular subset of programming languages.

10"

Which statement is FALSE?

Page 11: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Just Enough UML (ESaaS §11.2)!Armando Fox"

© 2013 Armando Fox & David Patterson, all rights reserved

Page 12: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Just Enough UML"

•  Unified Modeling Language: notation for describing various artifacts in OOP systems"

•  One type of UML diagram is a class diagram, showing class relationships and principal methods:"–  Car is a subclass of Vehicle –  Engine is a component of Car –  Engine class includes start(), stop() methods"

Page 13: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Relationships"

transfer_to_customerrefund

pricesold_on

Item

fund_codeDonationmerge_with

expunge!

nameemailsubscriber?

Customer merge_withexpunge!

nameseason

Vouchertype

reserve!redeemable_for_show?

reserved?changeable?

Voucher

0..*1

1

AccountCode

revenue_per_seat

date_and_timestart_salesend_saleshouse_capacity

Showdate

1

1

1

revenue_per_seat

namelist_starting

Show1

0..*

0..*

1..*0..*

0..*

Aggregation"

Composition"Inheritance"

Page 14: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

(Too Much UML)"

Page 15: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Show has many Vouchers, through Showdate ☐

Item has one AccountCode ☐

Customer has many Donations ☐

Voucher belongs to Vouchertype ☐ 15"

Which AR relationship DOES NOT follow from this UML diagram:"

transfer_to_customerrefund

pricesold_on

Item

fund_codeDonationmerge_with

expunge!

nameemailsubscriber?

Customer merge_withexpunge!

nameseason

Vouchertype

reserve!redeemable_for_show?

reserved?changeable?

Voucher

0..*1

1

AccountCode

revenue_per_seat

date_and_timestart_salesend_saleshouse_capacity

Showdate

1

1

1

revenue_per_seat

namelist_starting

Show1

0..*

0..*

1..*0..*

0..*

Page 16: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

This day in computing history"

Page 17: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Single Responsibility Principle (ESaaS §11.3)!Armando Fox"

© 2013 Armando Fox & David Patterson, all rights reserved

Page 18: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Single Responsibility Principle (SRP)"

•  A class should have one and only one reason to change"– Each responsibility is a possible axis of change"– Changes to one axis shouldn’t affect others"

•  What is class’s responsibility, in ≤25 words? "– Part of the craft of OO design is defining

responsibilities and then sticking to them"•  Models with many sets of behaviors"

– eg a user is a moviegoer, and an authentication principal, and a social network member, ...etc."

–  really big class files are a tipoff"

Page 19: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Lack of Cohesion of Methods"•  Revised Henderson-Sellers

LCOM=1–(sum(MVi) / M*V) (between 0 and 1)"–  M = # instance methods"–  V = # instance variables"–  MVi = # instance methods that access the i’th instance

variable (excluding “trivial” getters/setters)"•  LCOM-4 counts # of connected components in

graph where related methods are connected by an edge"

•  High LCOM suggests possible SRP violation "

19"

Page 20: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Do AR models violate SRP?"

•  They seem to mix behaviors in 1 class"–  they know how to load, save, delete themselves"–  they know about associations"–  they know about validations"– all in addition to model-specific business logic"

•  Although most ActiveRecord behaviors are included as modules"

Page 21: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Extract a module or class"

•  has_one or composed_of? "•  Use composition & delegation? "

name

Moviegoer 11

check_zipcodeformat_phone_number

phone_number

zipcode

Address

check_zipcodeformat_phone_number

name

phone_number

zipcode

Moviegoer

AR::Base

name, name=email, email=

@address@identity

Customer

valid_zip?canonicalize_street street, street=

zip, zip=

Address

vip?name, name=

email, email=

Identity

street, street=zip, zip=

http://pastebin.com/XESSSNb6

http://pastebin.com/bjdaTWN8

Page 22: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

In general, we would expect to see a correlation between poor cohesion score and poor SOFA metrics

Low cohesion is a possible indicator of an opportunity to extract a class

If a class respects SRP, its methods probably respect SOFA

If a class’s methods respect SOFA, the class probably respects SRP

22"

Which is true about a class’s observance of the Single Responsibility Principle?

Page 23: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Open/Closed Principle (ESaaS §11.4)!Armando Fox"

© 2013 Armando Fox & David Patterson, all rights reserved

Page 24: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Open/Closed Principle"

•  Classes should be open for extension, but closed for source modification"

class Report def output_report case @format when :html HtmlFormatter.new(self).output when :pdf PdfFormatter.new(self).output

•  Can’t extend (add new report types) without changing Report base class"

–  Not as bad as in statically typed language....but still ugly"

Page 25: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Abstract Factory Pattern:DRYing out construction"

•  How to avoid OCP violation in Report constructor, if output type isn’t known until runtime?"

•  Statically typed language: abstract factory pattern"•  Ruby has a particularly simple implementation of

this pattern…"http://pastebin.com/p3AHMqHZ

Page 26: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Template Method Pattern & Strategy Pattern"

•  Template method: set of steps is the same, but implementation of steps different"–  Inheritance: subclasses override abstract “step” methods"

•  Strategy: task is the same, but many ways to do it"–  composition: component classes implement whole task !

Page 27: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Template method stays the same;"helpers overridden in subclass"

Report Generation Using Template"

class Report attr_accessor :title, :text def output_report output_title output_header output_body end end

class HtmlReport < Report def output_title ... end def output_header ... end end class PdfReport < Report def output_title ... end def output_header ... end end

HtmlReport

output_title() output_header() output_body()

PdfReport

output_title() output_header() output_body()

Report

output_report() output_title() output_header() output_body()

Page 28: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Delegation"(vs. inheritance)"

Report Generation Using Strategy"

class Report attr_accessor :title, :text, :formatter def output_report formatter.output_report end end

Report

@formatter

output_report()

Formatter

output_report()

HtmlFormatter

output_report()

PdfFormatter

output_report()

“Prefer composition over inheritance”"

Page 29: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Decorator Pattern: DRYing Out Extension Points"

output()add_watermark()

@base

PdfWithWatermark-Formatter

output()protect_with_password()

@base

PdfWithPassword-Formatter

output()PdfFormatter

output()Formatter

output()

PdfWithPassword-Formatter

output()

PdfWithWatermark-Formatter

output()

PdfWithPasswordAnd-WatermarkFormatter

output()HtmlFormatter

output()RegularPdfFormatter

output()PdfFormatter

output()Formatter

Example in Rails: ActiveRecord scopes"

Movie.for_kids.with_good_reviews(3) Movie.with_many_fans.recently_reviewed

Another example of composition over inheritance!"

Page 30: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

OCP In Practice"

•  Can’t close against all types of changes, so have to choose, and you might be wrong"

•  Agile methodology can help expose important types of changes early!– Scenario-driven design with prioritized features"– Short iterations"– Test-first development"

•  Then you can try to close against those types of changes "

Page 31: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

OmniAuth is itself compliant with OCP ☐

Using OmniAuth helps your app follow OCP (with respect to 3rd-party authentication)

OmniAuth is an example of the Template pattern ☐

OmniAuth is an example of the Strategy pattern ☐

31"

OmniAuth defines a handful of RESTful endpoints your app must provide to handle authentication with a variety of third parties. To add a new auth provider, you create a gem that works with that provider. Which statement is FALSE about OmniAuth?

Page 32: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Liskov Substitution Principle (ESaaS §11.5)!

© 2013 Armando Fox & David Patterson, all rights reserved

Page 33: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Liskov Substitution: Subtypes can substitute for base types"

•  Current formulation attributed to (Turing Award winner) Barbara Liskov"

•  Let’s see an example"

•  Type/subtype != class/subclassWith duck typing, substitutability depends on how collaborators interact with object"

“A method that works on an instance of type T, should also work on any subtype of T”"

http://pastebin.com/nf2D9RYj

Page 34: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Contracts"•  Composition, vs. (misuse of) inheritance"•  If can’t express consistent assumptions

about “contract” between class & collaborators, likely LSP violation"– Symptom: change to subclass requires change

to superclass (shotgun surgery) "

Square

@rect

area(), perimeter()

Rectangle

width, height

area(), perimeter()

Rectangle

area, perimeter

width, height

Square

make_twice_as_wide_as_high

Page 35: Patterns, Antipatterns, and SOLID - WordPress.com · 2014-01-10 · Design Patterns Promote Reuse" “A pattern describes a problem that occurs often, along with a tried solution

Only (a) is true ☐

Only (b) is true ☐

Both (a) and (b) are true ☐

Neither (a) nor (b) is true ☐

35"

(a) In duck-typed languages, LSP violations can occur even when inheritance is not used (b) In statically-typed languages, if the compiler reports no type errors/warnings, then there are no LSP violations

http://pastebin.com/rLguzt8X