2010年11月16日火曜日

第6章 Prototypeパターン : コピーしてインスタンスを作る with python



早いものでもう第6章。今回はPrototypeパターンです。

第4章のFactory Methodパターン( http://ksk77.blogspot.com/2010/11/4-factory-method.html )に似ているのですが、大きく違うところが一点。

  • 『生成』ではなく『コピー』

この違いのため、以下のように焦点が異なっています。

  • 前回は作る側(Factory)に焦点を当てて生成のメソッド(factoryMethod)なんかを作っていた
  • 今回は作られる側(Prototype)に焦点を当ててコピーを作るメソッド(createClone)なんかを作っている


こうやって自分なりの解釈を付けていきながら読み進めていこう。

以下、pythonでの実装。(と書くのも一々面倒なのでタイトルにpythonって書いておきました。) pythonではオブジェクトのコピーを copy モジュールに独立に用意しているので分かりやすいです。
なお、練習問題6-1を参考に、PrototypeにcreateClone()を実装してあります。

実行結果

"Hello, world."
 ~~~~~~~~~~~~~ 
*****************
* Hello, world. *
*****************
/////////////////
/ Hello, world. /
/////////////////

ソースコード

framework.py
# -*- coding: utf8 -*-

import copy

class Manager:
    def __init__(self): self.__showcase = dict()
    def register(self, name, proto): self.__showcase[name] = proto
    def create(self, name): return copy.deepcopy(self.__showcase[name])

class Prototype:
    def use(self): raise NotImplementedError
    def createClone(self): return copy.deepcopy(self)

main.py
#!/usr/bin/env python
# -*- coding: utf8 -*-

from framework import Manager, Prototype

class MessageBox(Prototype):
    def __init__(self, decochar): self.decochar = decochar
    def use(self, message):
        import sys
        for i in xrange(len(message)+3): sys.stdout.write(self.decochar)
        print self.decochar
        print "%c %s %c" % (self.decochar, message, self.decochar)
        for i in xrange(len(message)+3): sys.stdout.write(self.decochar)
        print self.decochar

class UnderlinePen(Prototype):
    def __init__(self, ulchar): self.ulchar = ulchar
    def use(self, message):
        import sys
        print "\""+message+"\""
        sys.stdout.write(" ")
        for i in xrange(len(message)): sys.stdout.write(self.ulchar)
        print " "

def main():
    # prepare
    manager = Manager()
    upen = UnderlinePen("~")
    mbox = MessageBox("*")
    sbox = MessageBox("/")
    manager.register("strong message", upen)
    manager.register("warning box", mbox)
    manager.register("slash box", sbox)

    # create
    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.")

if __name__=='__main__': main()

0 件のコメント:

コメントを投稿