目指そうかなRubyist RSSフィード

 | 

2007-03-22

[designpattern] Prototypeパターン  [designpattern] Prototypeパターン - 目指そうかなRubyist を含むブックマーク はてなブックマーク -  [designpattern] Prototypeパターン - 目指そうかなRubyist  [designpattern] Prototypeパターン - 目指そうかなRubyist のブックマークコメント

クラスからインスタンスを生成するのではなくインスタンスコピーしてあたらしいインスタンスを生成する。

ソース

class Product
  def use(string)
  end

  def createClone
    self.dup
  end
end

class Manager
  def initialize
    @hash = {}
  end

  def register(name, product)
    @hash[name] = product
  end

  def create(name)
    p = @hash[name]
    p.createClone
  end
end

class MessageBox < Product
  def initialize(decochar)
    @decochar = decochar
  end

  def use(string)
    puts @decochar * (string.length + 4)
    puts @decochar + ' ' +  string + ' ' + @decochar
    puts @decochar * (string.length + 4)
  end
end

class UnderlinePen < Product
  def initialize(ulchar)
    @ulchar = ulchar
  end

  def use(string)
    puts "\"" + string + "\""
    puts ' ' + @ulchar * string.length
  end
end

if __FILE__ == $0 
  manager = Manager.new
  upen = UnderlinePen.new('~')
  mbox = MessageBox.new('*')
  sbox = MessageBox.new('/')
  manager.register('strong message', upen)
  manager.register('warning box', mbox)
  manager.register('slash box', sbox)
  p1 = manager.create('strong message')
  p1.use('hello world!')
  p2 = manager.create('warning box')
  p2.use('hello world!')
  p3 = manager.create('slash box')
  p3.use('hello world!')
end

学んだこと

登場人物
  • prototype
  • concreateprototype
  • client

上の例ではprototypeはProductクラス担当

congreateprototypeはMessageBoxクラスUnderlineクラス担当

なぜprototypeパターンを使うのか?
クラス名の束縛

クラス名がManagerクラスに入っていないことがポイント

クラス名と切り離して再利用可能。

上のコードなら練習問題6-1のcreateCloneメソッドを共有されてるからOK

[designpattern] Singletonパターン  [designpattern] Singletonパターン - 目指そうかなRubyist を含むブックマーク はてなブックマーク -  [designpattern] Singletonパターン - 目指そうかなRubyist  [designpattern] Singletonパターン - 目指そうかなRubyist のブックマークコメント

Singletonパターン

インスタンスが一つしか存在しないことを保証するパターン

ソース

require 'test/unit'
require 'singleton'

class Test_singleton < Test::Unit::TestCase
  def test_singleton
    obj1 = MySingleton.instance
    obj2 = MySingleton.instance
    assert_equal obj1,obj2
  end

  def test_singleton_error
    assert_raise(NoMethodError){ MySingleton.new }
  end
end

class MySingleton
  include Singleton
end

学んだこと

rubyにはsingletonライブラリがすでにあることがわかった。

でも謎なのはこれいつインスタンスが生成されているのかわからないこと。

練習問題5-1

TicketMakerクラス(getNextTicketNumberメソッドを呼ぶたびに1000,1001,1002…という数をじゅんに返す)。このクラスSingletonパターンを当てはめてインスタンスが一つしか作れないようにしてください。

解答

require 'test/unit'
require 'singleton'

class Test_TicketMaker < Test::Unit::TestCase
  def test_singleton
    obj1 = TicketMaker.instance
    obj2 = TicketMaker.instance
    assert_equal obj1, obj2
  end

  def test_getNextTicketNumber
    obj1 = TicketMaker.instance
    assert_equal 1001, obj1.getNextTicketNumber
    assert_equal 1002, obj1.getNextTicketNumber
    assert_equal 1003, obj1.getNextTicketNumber
  end

  def test_singleton_error
    assert_raise(NoMethodError) { TicketMaker.new}
  end
end

class TicketMaker
  include Singleton
  def initialize
    @ticket = 1000
  end

  def getNextTicketNumber
    @ticket += 1
  end
end
 |