techtalk design patterns

43
DESIGN PATTERNS Teeeechhh taaaaalkkkk

Upload: jan-berdajs

Post on 14-Jun-2015

144 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Techtalk design patterns

DESIGN PATTERNSTeeeechhh taaaaalkkkk

Page 2: Techtalk design patterns

A design pattern is a general reusable solution to a commonly occurring problem within a given context in software design. A design pattern is not a finished design that can be transformed

directly into source or machine code. It is a description or template for how to solve a problem that can be used in many

different situations.

The Gang of Four (GoF)

Page 3: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 4: Techtalk design patterns

• Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 5: Techtalk design patterns

class Report! def initialize! @title = 'Monthly Report'! @text = ['Things are going', 'really, really well.']! end!! def output_report(format)! if format == :plain! puts("*** #{@title} ***")! elsif format == :html! puts('<html>')! puts(' <head>')! puts(" <title>#{@title}</title>")! puts(' </head>')! puts(' <body>')! else! raise "Unknown format: #{format}"! end!! @text.each do |line|! if format == :plain! puts(line)! else! puts(" <p>#{line}</p>" )! end! end!! if format == :html! puts(' </body>')! puts('</html>')! end! end!end!

Page 6: Techtalk design patterns

class Report! def initialize! @title = 'Monthly Report'! @text = ['Things are going', 'really, really well.']! end!! def output_report! output_start! output_head! output_body_start! @text.each do |line|! output_line(line)! end! output_body_end! output_end! end!! def output_start! end!! def output_head! raise 'Called abstract method: output_head'! end!! def output_body_start! end!! def output_line(line)! raise 'Called abstract method: output_line'! end!! def output_body_end! end!! def output_end! end!end!

Template method

Page 7: Techtalk design patterns

class HTMLReport < Report! def output_start! puts('<html>')! end!! def output_head! puts(' <head>')! puts(" <title>#{@title}</title>")! puts(' </head>')! end!! def output_body_start! puts('<body>')! end!! def output_line(line)! puts(" <p>#{line}</p>")! end!! def output_body_end! puts('</body>')! end!! def output_end! puts('</html>')! end!end!

Page 8: Techtalk design patterns

•Template Method

• Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 9: Techtalk design patterns

class Report! attr_reader :title, :text! attr_accessor :formatter!! def initialize(formatter)! @title = 'Monthly Report'! @text = ['Things are going', 'really, really well.']! @formatter = formatter! end!! def output_report! @formatter.output_report(self)! end!end!!Report.new(HTMLFormatter.new)

Page 10: Techtalk design patterns

class HTMLFormatter! def output_report(context)! puts('<html>')! puts(' <head>')! # Output The rest of the report ...!! puts(" <title>#{context.title}</title>")! puts(' </head>')! puts(' <body>')! context.text.each do |line|! puts(" <p>#{line}</p>")! end! puts(' </body>')!! puts('</html>')! end!end!

Page 11: Techtalk design patterns

•Template Method

•Strategy

• Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 12: Techtalk design patterns

class User! def save! save_to_database! if new_record?! notify_observers(:after_create)! end! notify_observers(:after_save)! end!end!!class UserEmailObserver! def after_create(user)! UserMailer.welcome_email(user)! end!end!!user = User.new!user.add_observer(UserEmailObserver.new)!

Page 13: Techtalk design patterns

•Template Method

•Strategy

•Observer

• Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 14: Techtalk design patterns

class Task! attr_reader :name!! def initialize(name)! @name = name! end!! def get_time_required! 0.0! end!end

Page 15: Techtalk design patterns

class CompositeTask < Task ! def initialize(name)! super(name)! @sub_tasks = []! end!! def add_sub_task(task)! @sub_tasks << task! end!! def remove_sub_task(task)! @sub_tasks.delete(task)! end!! def get_time_required! time=0.0! @sub_tasks.each {|task| time += task.get_time_required}! time! end!end!

Page 16: Techtalk design patterns

class MakeCakeTask < CompositeTask! def initialize! super('Make cake')! add_sub_task( MakeBatterTask.new )! add_sub_task( FillPanTask.new )! add_sub_task( BakeTask.new )! add_sub_task( FrostTask.new )! add_sub_task( LickSpoonTask.new )! end!end!!MakeCakeTask.new.get_time_required

Page 17: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 18: Techtalk design patterns

External

array = ['red', 'green', 'blue']!!i = ArrayIterator.new(array)!while i.has_next?! puts "item: #{i.next_item}"!end!

Hello Java ;-)

Page 19: Techtalk design patterns

Internal

array = ['red', 'green', 'blue']!array.each do |item|! puts "item: #{item}"!end!

Page 20: Techtalk design patterns

External

array1 = [1, 2]!array1 = [2, 3]!!sum = 0!i1 = ArrayIterator.new(array1)!i2 = ArrayIterator.new(array2)!while i1.has_next? && i2.has_next?! sum += i1.next_item * i2.next_item!end!

Page 21: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

• Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 22: Techtalk design patterns

Primer Template Method

class SlickButton! def on_button_push! raise "Abstract method on_button_push"! end!end!!class SaveButton < SlickButton! def on_button_push! document.save(filename)! end!end

So many subclasses :-(

Page 23: Techtalk design patterns

class SlickButton! attr_accessor :command!! def initialize(command)! @command = command! end!! def on_button_push! @command.execute if @command! end!end!!class SaveCommand! def execute! # Save the current document...! end!end!

Command Pattern

Page 24: Techtalk design patterns

class SlickButton! attr_accessor :command!! def initialize(&block)! @command = block! end!! def on_button_push! @command.call if @command! end!end!!save_button = SlickButton.new do! document.save(filename)!end!

Lambda

Page 25: Techtalk design patterns

Composite, CommandPRIMER - INSTALLER

Page 26: Techtalk design patterns

class Command! attr_reader :description!! def initialize(description)! @description = description! end!! def execute! end!! def unexecute! end!end!!class CreateFile < Command! def initialize(path, contents)! super "Create file: #{path}"! @path = path! @contents = contents! end!! def execute! f = File.open(@path, "w")! f.write(@contents)! f.close! end!! def unexecute! File.delete(@path)! end!end!

Page 27: Techtalk design patterns

class CompositeCommand < Command! def initialize! @commands = []! end!! def add_command(cmd)! @commands << cmd! end!! def execute! @commands.each { |cmd| cmd.execute }! end!! # ...!! def unexecute! @commands.reverse.each { |cmd| cmd.unexecute }! end!! # ...!! def description! description = ''! @commands.each { |cmd| description += cmd.description + "\n" }! return description! end!end!

Page 28: Techtalk design patterns

class Installer < CompositeCommand! def initialize! add_command(CreateFile.new("file1.txt", "hello world\n"))! add_command(CopyFile.new("file1.txt", "file2.txt"))! add_command(DeleteFile.new("file1.txt"))! end!end!!installer = Installer.new!installer.execute!puts installer.description!

Page 29: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

• Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 30: Techtalk design patterns

class Database! def initialize(adapter)! @adapter = adapter! end!! def create_table(table_name, fields)! @adapter.create_table(table_name)! fields.each_pair do |name, type|! @adapter.create_column(table_name, name, type)! end! end!end!!db = Database.new(MySQLAdapter.new(DB_URI))!db.create_table(:users, email: :string)!

Page 31: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

• Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 32: Techtalk design patterns

class AccountProtectionProxy! def initialize(real_account, owner_name)! @subject = real_account! @owner_name = owner_name! end!! def withdraw(amount)! check_access! return @subject.withdraw(amount)! end!! def check_access! if Etc.getlogin != @owner_name ! raise "Illegal access: #{Etc.getlogin} cannot access account."! end! end!end!

Page 33: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

• Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 34: Techtalk design patterns

class UserDecorator! attr_reader :user! delegate :first_name, :last_name,! :position, :institution, to: :user!! def initialize(user)! @user = user! end!! def short_name! "#{first_name[0]}. #{last_name}"! end!! def description! "#{short_name} is a #{position} at #{institution}"! end!end!

<p>! <b>Name:<b>! {{short_name}}! <br>! {{description}}!<p>!

Page 35: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

• Singleton

•Factory

•Builder

• Interpreter

Page 36: Techtalk design patterns

class SimpleLogger! @@instance = SimpleLogger.new!! def self.instance! return @@instance! end!! def warn(s)! puts s! end!end!!SimpleLogger.instance.warn("I don't know what I'm doing")!

Page 37: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

• Factory

•Builder

• Interpreter

Page 38: Techtalk design patterns

factory :user do! first_name 'John'! last_name 'Doe'! admin false!! factory :admin do! admin true! end!end!!FactoryGirl.build(:user)!FactoryGirl.build(:admin)!

Page 39: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

• Builder

• Interpreter

Page 40: Techtalk design patterns

user = UserBuilder.new('John', 'Doe')! .age(30)! .phone('1234567')! .address('Fake address 1234')! .build()!

Hello Java ;-)

Page 41: Techtalk design patterns

•Template Method

•Strategy

•Observer

•Composite

• Iterator

•Command

•Adapter

•Proxy

•Decorator

•Singleton

•Factory

•Builder

• Interpreter

Page 42: Techtalk design patterns

AST (Abstract Syntax Tree) querying stuff, building SQL, etc.

# Files that are bigger than 20KB and not writable,!# or are mp3 files!expr = Or.new(! And.new(Bigger.new(20.kilobytes), Not.new(Writable.new)),! FileName.new('*.mp3'))!expr.evaluate # => [File, File, ...]!

Page 43: Techtalk design patterns

• teamleadi določite enega ki naj v naslednji 1 uri uporabi na projektu enega od patternov

•checkmarks