Top Banner
DESIGN PATTERNS Teeeechhh taaaaalkkkk
43

Techtalk design patterns

Jun 14, 2015

Download

Technology

Jan Berdajs
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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