Dpir 2014 abstractions

64
@russolsen Design Patterns in Ruby 1

Transcript of Dpir 2014 abstractions

@russolsen

Design Patterns in

Ruby

1

2

FORTRAN

BASIC

Pascal

Python

C++C

Java

RubyClojureGo

3

4

Design Patterns What are they?

Some Examples

The Good & Bad

5

What is a

Design Pattern?

6

7

Prepackaged Solution

Common Problem

8

9Main Street

10Main Street??

11Main Street??

12

h

Main Street

13

2hh

Main Street

Name: Main Street

Problem: Open Feeling

Solution: Width = 2 * Ht

14

1) Prepackaged Solutions

15

Why Bother?

1) Prepackaged Solutions

2) Examples of Good Design

16

Why Bother?

1) Prepackaged Solutions

2) Examples of Good Design

3) Big Ideas

!

17

Why Bother?

Some Examples

18

Name: Template Method

Problem:

Solution:

19

Name: Template Method

Problem:Varying details

Solution:

20

Documents &

Rendering 21

template*.rb

22Template Method

Document!def render render_title(title) text.each_line do|l| render_line(l) end ...

PlainDocumentdef render_title(t) end !def render_line(l) end

HtmlDocumentdef render_title(t) end !def render_line(l) end

23Abstract Animals

Mammal

Lion Squirrel

Name: Template Method

Problem:Varying details

Solution: Push the details into a subclass

24

Big Ideas 1) Abstractions!

2) Separate out change

!

25

The Problem is

!

26

The Problem is

Commitment 27

# I start off fine!

doc1 = HtmlDocument.new(…)

28

# I start off fine!

doc1 = HtmlDocument.new(…)

# But then I need to render doc1 in plain text…

29

# I start off fine!

doc1 = HtmlDocument.new(…)

# But then I need to render doc1 in plain text…

doc2 = PlainDocument.new(doc1.title, doc1.text)

doc2.render

30

Try Again

31strategy.rb

Strategy Pattern

32

33Strategy

Document

def render @renderer.render(self) end

HtmlRendererdef render(doc) puts “<title>” puts @doc.title puts “</title>” … end

PlainRendererdef render(doc) puts doc.title ... end

34Strategy

Document

def render @renderer.render(self) end

HtmlRendererdef render(doc) puts “<title>” puts @doc.title puts “</title>” … end

PlainRenderdef render(doc) puts doc.title ... end

35Helpers

Homeowner

Electrician

Plumber

Name: Strategy

Problem:Varying details

Solution: Push the whole job into a separate object

36

Big Ideas 1) Abstractions!

2) Separate out change

3) Composition over inheritance

37

A Different Problem

38Obs*.rb

Observer Pattern

39

40Observer Pattern

Document

def text=(t) @observers.each {…} end

Viewdef on_doc_change(doc) puts “<title>” puts @doc.title puts “</title>” … end

Databasedef on_doc_change(doc) # Save the doc ... end

41Observer Pattern

42Observer Pattern

43Observer Pattern

Amazon

Clinton

Russ

44Observer Pattern

Document

def text=(t) @observers.each {…} end

45Black Boxes

on_doc_change(doc) on_doc_change(doc)

Big Ideas 1) Abstractions!

2) Separate out change

3) Composition not inheritance

4) Interface not implementation

46

Good Bad

47

Good Orange Beatles

48

49

50

Bad Rampaging Patterns

51

52Strategy

Document

def render @renderer.render(self) end

HtmlRendererdef render(doc) puts “<title>” puts @doc.title puts “</title>” … end

PlainRenderdef render(doc) puts doc.title ... end

53

Renderer

Document

HtmlRenderer PlainRenderer

Strategy + Template

54

RendererDocument

HtmlRenderer PlainRenderer

Observer

Observer

Observer

Observer

Strategy + Insanity

Pain First

55

Big Ideas 1) Abstractions!

2) Separate out change

3) Composition not inheritance

4) Interface not implementation

5) Pain first, then the pattern56

Summary

57

Prepackaged Solution

Common Problem

58

59Template Method

Document!def render render_title(title) text.each_line do|l| render_line(l) end ...

PlainDocumentdef render_title(t) end !def render_line(l) end

HtmlDocumentdef render_title(t) end !def render_line(l) end

60Strategy

Document

def render @renderer.render(self) end

HtmlRendererdef render(doc) puts “<title>” puts @doc.title puts “</title>” … end

PlainRenderdef render(doc) puts doc.title ... end

61Observer Pattern

Document

def text=(t) @observers.each {…} end

Viewdef on_doc_change(doc) puts “<title>” puts @doc.title puts “</title>” … end

Databasedef on_doc_change(doc) # Save the doc ... end

Big Ideas 1) Abstractions!

2) Separate out change

3) Composition not inheritance

4) Interface not implementation

5) Pain first, then the pattern62

Questions?

63

[email protected] @russolsen

!

cognitect.com

64