Differences between revisions 2 and 52 (spanning 50 versions)
Revision 2 as of 2005-07-30 02:10:11
Size: 18
Editor: flyaflya
Comment:
Revision 52 as of 2009-12-25 07:10:09
Size: 14635
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
<<TableOfContents>>
## 请删除此页面
Line 2: Line 5:
== 介绍 ==

== 创建型模式 ==


=== singleton(单件) ===

==== 意图 ====
保证一个类仅有一个实例,并提供一个访问它的全局访问点。

==== 经典应用 ====
MFC中的App类,一般程序中用到的全局变量。

==== 实现代码 ====
{{{
#!python
class Singleton:
    """ A python singleton """

    class __impl:
        """ Implementation of the singleton interface """

        def spam(self):
            """ Test method, return singleton id """
            return id(self)

    # storage for the instance reference
    __instance = None

    def __init__(self):
        """ Create singleton instance """
        # Check whether we already have an instance
        if Singleton.__instance is None:
            # Create and remember instance
            Singleton.__instance = Singleton.__impl()

        # Store instance reference as the only member in the handle
        self.__dict__['_Singleton__instance'] = Singleton.__instance

    def __getattr__(self, attr):
        """ Delegate access to implementation """
        return getattr(self.__instance, attr)

    def __setattr__(self, attr, value):
        """ Delegate access to implementation """
        return setattr(self.__instance, attr, value)


# Test it
s1 = Singleton()
print id(s1), s1.spam()

s2 = Singleton()
print id(s2), s2.spam()

# Sample output, the second (inner) id is constant:
# 8172684 8176268
# 8168588 8176268
}}}

==== 另一个实现代码 ====

从[[http://members.chello.nl/f.niessink/|TaskCoach]]的代码中摘抄,因此许可证为GPL。
-- QiangningHong



{{{
#!python
class Singleton(type):
    """Singleton Metaclass"""

    def __init__(cls, name, bases, dic):
        super(Singleton, cls).__init__(name, bases, dic)
        cls.instance = None

    def __call__(cls, *args, **kwargs):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
        return cls.instance
}}}

使用方法:
{{{
#!python
class MyClass(object):
    __metaclass__ = Singleton

ob1 = MyClass()
ob2 = MyClass()
assert ob1 is ob2
}}}

== 结构型模式 ==
=== Proxy(代理) ===
==== 意图 ====
为其他对象提供一种代理以控制对这个对象的访问。<<BR>>
{{attachment:ProxyPattern.gif}}
==== 代码 ====
{{{
#!python
class Proxy:
    def __init__( self, subject ):
        self.__subject = subject
    def __getattr__( self, name ):
        return getattr( self.__subject, name )
}}}
==== 例子 ====
{{{
#!python

class RGB:
    def __init__( self, red, green, blue ):
        self.__red = red
        self.__green = green
        self.__blue = blue
    def Red( self ):
        return self.__red
    def Green( self ):
        return self.__green
    def Blue( self ):
        return self.__blue

}}}
使用Proxy改变Blue函数:
{{{
#!python
class NoBlueProxy( Proxy ):
    def Blue( self ):
        return 0
}}}
使用:
>>> rgb = RGB( 100, 192, 240 )

>>> rgb.Red()

100

>>> proxy = Proxy( rgb )

>>> proxy.Green()

192

>>> noblue = NoBlueProxy( rgb )

>>> noblue.Green()

192

>>> noblue.Blue()

0

}}}
使用:
>>> rgb = RGB( 100, 192, 240 )

>>> rgb.Red()

100

>>> proxy = Proxy( rgb )

>>> proxy.Green()

192

>>> noblue = NoBlueProxy( rgb )

>>> noblue.Green()

192

>>> noblue.Blue()

0
==== 特殊说明 ====
 * 因为在Proxy中没有__setattr__函数,因此只可以得到rgb中的值,但不能改变,比如可以"r = noblue._RBG__red",但不能写"noblue._RBG__red = 255",如果要想改变RBG中的值,只有在RBG中定义一些函数如"setBlue...",在noblue中直接调用。
 * 在Proxy中也不能定义__setattr__,否则在__init__中会发生死循环。

=== flyweight ===
==== 意图 ====
运用共享技术有效地支持大量细粒度的对象。
==== 实现代码 ====
{{{
#!python
#实现过程类似于singleton模式

import weakref
#weekref产生的value不能保持对象存在。当对象不包括weakref在内的引用计数达到0时,对象将被删除。

class Instrument(object):
    _InstrumentPool = weakref.WeakValueDictionary()

    def __new__(cls, name):
        '''Instrument(name)
        Create a new instrument object, or return an existing one'''
        obj = Instrument._InstrumentPool.get(name, None)

        if not obj:
            print "new",name
            obj = object.__new__(cls)
            Instrument._InstrumentPool[name] = obj

        return obj

    def __init__(self, name):
        '''Complete object construction'''
        self.name = name
        print "New instrument @%04x, %s" % (id(self), name)

        # ... connect instrument to datasource ...

#测试
import unittest

class InstrumentTests(unittest.TestCase):
    def testInstrument(self):
        ibm1 = Instrument("IBM")
        ms = Instrument("MS")
        ibm2 = Instrument("IBM")
        self.assertEquals(id(ibm1), id(ibm2))
        self.assertNotEquals(id(ibm1), id(ms))

        self.assertEquals(2, len(Instrument._InstrumentPool),
            "Total instruments allocated")

        # This bit assumes CPython memory allocation:
        del(ibm1)
        del(ibm2)
        # 每一次调用Instrument,因其函数__new__中的Instrument._InstrumentPool[name]是weakref,只有obj = object.__new__(cls)引用一次。所以del(ibm1)和del(imb2)后引用计数达到0,对象被清理。
        self.assertEquals(1, len(Instrument._InstrumentPool),
            "Total instruments allocated")


if __name__=='__main__':
    unittest.main()
}}}

== 行为模式 ==
=== Chain of Responsibility(职责链) ===
==== 意图 ====
使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。
==== 说明 ====
用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。
例如,窗口UI对消息的处理:<<BR>>
{{attachment:CORPattern.gif}}
==== 代码实现 ====
模拟UI对消息的处理
{{{
#!python
class Event:
    def __init__( self, name ):
        self.name = name

class Widget:
    def __init__( self, parent = None ):
        self.__parent = parent
    def Handle( self, event ):
        handler = 'Handle_' + event.name
        if hasattr( self, handler ):
            method = getattr( self, handler )
            method( event )
        elif self.__parent:
            self.__parent.Handle( event )
        elif hasattr( self, 'HandleDefault' ):
            self.HandleDefault( event )
}}}

使用:
当用一个event被Handle,将调用Handle_"event.name",如果没有此函数就调用parent来处理此event,如果还没有被处理,就试着交给HandleDefault()。
例如:
{{{
#!python
class MainWindow(Widget):
    def Handle_close( self, event ):
        print 'MainWindow: ' + event.name
    def HandleDefault( self, event ):
        print 'Default: ' + event.name
        
class Button( Widget ):
    def Handle_click( self, event ):
        print 'Button: ' + event.name
}}}


=== Observer(观察者) ===
==== 意图 ====
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
==== 经典应用 ====
MFC中document类对所有view的更新,ddx/ddv对窗口上控件的更新。
==== 代码实现 ====
{{{
#!python
class Subject:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        if not observer in self._observers:
            self._observers.append(observer)

    def detach(self, observer):
        try:
            self._observers.remove(observer)
        except ValueError:
            pass

    def notify(self, modifier=None):
        for observer in self._observers:
            if modifier != observer:
                observer.update(self)
}}}
==== 例子,用法 ====
{{{
#!python
# Example usage
class Data(Subject):
    def __init__(self, name=''):
        Subject.__init__(self)
        self.name = name
        self.data = 0

    def setData(self, data):
        self.data = data
        self.notify()

    def getData(self):
        return self.data


class HexViewer:
    def update(self, subject):
        print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.getData())


class DecimalViewer:
    def update(self, subject):
        print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.getData())


# Example usage...
def main():
    data1 = Data('Data 1')
    data2 = Data('Data 2')
    view1 = DecimalViewer()
    view2 = HexViewer()
    data1.attach(view1)
    data1.attach(view2)
    data2.attach(view2)
    data2.attach(view1)

    print "Setting Data 1 = 10"
    data1.setData(10)
    print "Setting Data 2 = 15"
    data2.setData(15)
    print "Setting Data 1 = 3"
    data1.setData(3)
    print "Setting Data 2 = 5"
    data2.setData(5)
    print "Detach HexViewer from data1 and data2."
    data1.detach(view2)
    data2.detach(view2)
    print "Setting Data 1 = 10"
    data1.setData(10)
    print "Setting Data 2 = 15"
    data2.setData(15)
}}}
=== Template Method(模板方法) ===
==== 意图 ====
定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。
==== 实现代码 ====
{{{
#!python
class Base:
    def doAll(self):
        self.doThis()
        self.doThat()
    
class Foo(Base):
    def doThis(self):
        print "do this"
    def doThat(self):
        print "do that"

#测试
Foo a
a.doAll()
#输出
#do this
#do that
}}}
=== Visitor(访问者) ===
==== 意图 ====
作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.
==== 实现代码 ====
{{{
#!python
class Visitor:
    def __init__(self):
        self._methodDic={}

    def default(self, other):
        print "What's this:", other

    def addMethod(self, method):
        self._methodDic[method.getKey()]=method

    def __call__(self, other):
        method=self._methodDic.get(\
                other.__class__.__name__,self.default)
        return method(other)
}}}
==== 用法、例子 ====
在MyVisit的函数__call__中定义对target的具体访问操作。
{{{
#!python
class MyVisit:
    """
    Instead of deriving from Visitor the work is
    done by instances with this interface.
    """
    def __init__(self, otherClass):
        self._msg='Visit: %s'%otherClass.__name__
        self._key=otherClass.__name__

    def __call__(self, target):
        print self._msg, target

    def getKey(self):
        return self._key

# 被访问者
class E1:pass
class E2:pass
class E3:pass

# 用法

collection=[E1(), E1(), E2(), E3()]

visitor=Visitor()
visitor.addMethod(MyVisit(E1))
visitor.addMethod(MyVisit(E2))

map(visitor, collection)
}}}
###########################
输出:

Visit: E1 <__main__.E1 instance at 7ff6d0>

Visit: E1 <__main__.E1 instance at 7ff730>

Visit: E2 <__main__.E2 instance at 7ff780>

What's this: <__main__.E3 instance at 7ff7b0>


# 简化用法
{{{
#!python
visitor = Visitor()
visitor.addMethod(MyVisit(E1))
a = E1()
visitor(a)
}}}
#########################
输出:

Visit: E1 <__main__.E1 instance at 0x00A91EE0>

=== Command(命令) ===
==== 意图 ====
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。在python中叫“Command Dispatch Pattern”,也不需要将请求封装成对象,直接用字符串作命令请求。
==== 实现代码 ====
{{{
#!python
class Dispatcher:

    def do_get(self):
     print("do_get")

    def do_put(self):
     print("d0_put")
   
    def error(self):
     print("error")

    def dispatch(self, command):
        mname = 'do_' + command
        if hasattr(self, mname):
            method = getattr(self, mname)
            method()
        else:
            self.error()
}}}
==== 用法 ====
{{{
#!python
Dispatcher a
a.dispatch("get")
a.dispatch("put")
}}}
=== state(代理) ===
==== 意图 ====
允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

==== 实现代码 ====
{{{
#!python
class NetworkCardState:
    """Abstract State Object"""
    def send(self):
        raise "NetworkCardState.send - not overwritten"
    
    def receive(self):
        raise "NetworkCardState.receive - not overwritten"

    
class Online(NetworkCardState):
    """Online state for NetworkCard"""
    def send(self):
        print "sending Data"
        
    def receive(self):
        print "receiving Data"


class Offline(NetworkCardState):
    """Offline state for NetworkCard"""
    def send(self):
        print "cannot send...Offline"
        
    def receive(self):
        print "cannot receive...Offline"

    
class NetworkCard:
    def __init__(self):
        self.online = Online()
        self.offline = Offline()
        ##default state is Offline
        self.currentState = self.offline
    
    def startConnection(self):
        self.currentState = self.online

    def stopConnection(self):
        self.currentState = self.offline
    
    def send(self):
        self.currentState.send()
        
    def receive(self):
        self.currentState.receive()
        

def main():
    myNetworkCard = NetworkCard()
    print "without connection:"
    myNetworkCard.send()
    myNetworkCard.receive()
    print "starting connection"
    myNetworkCard.startConnection()
    myNetworkCard.send()
    myNetworkCard.receive()

if __name__ == '__main__':
    main()
}}}
=== interpreter(解释器) ===
==== 意图 ====
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示
来解释语言中的句子。

设计模式

介绍

创建型模式

singleton(单件)

意图

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

经典应用

MFC中的App类,一般程序中用到的全局变量。

实现代码

   1 class Singleton:
   2     """ A python singleton """
   3 
   4     class __impl:
   5         """ Implementation of the singleton interface """
   6 
   7         def spam(self):
   8             """ Test method, return singleton id """
   9             return id(self)
  10 
  11     # storage for the instance reference
  12     __instance = None
  13 
  14     def __init__(self):
  15         """ Create singleton instance """
  16         # Check whether we already have an instance
  17         if Singleton.__instance is None:
  18             # Create and remember instance
  19             Singleton.__instance = Singleton.__impl()
  20 
  21         # Store instance reference as the only member in the handle
  22         self.__dict__['_Singleton__instance'] = Singleton.__instance
  23 
  24     def __getattr__(self, attr):
  25         """ Delegate access to implementation """
  26         return getattr(self.__instance, attr)
  27 
  28     def __setattr__(self, attr, value):
  29         """ Delegate access to implementation """
  30         return setattr(self.__instance, attr, value)
  31 
  32 
  33 # Test it
  34 s1 = Singleton()
  35 print id(s1), s1.spam()
  36 
  37 s2 = Singleton()
  38 print id(s2), s2.spam()
  39 
  40 # Sample output, the second (inner) id is constant:
  41 # 8172684 8176268
  42 # 8168588 8176268

另一个实现代码

TaskCoach的代码中摘抄,因此许可证为GPL。 -- QiangningHong

   1 class Singleton(type):
   2     """Singleton Metaclass"""
   3 
   4     def __init__(cls, name, bases, dic):
   5         super(Singleton, cls).__init__(name, bases, dic)
   6         cls.instance = None
   7 
   8     def __call__(cls, *args, **kwargs):
   9         if cls.instance is None:
  10             cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
  11         return cls.instance

使用方法:

   1 class MyClass(object):
   2     __metaclass__ = Singleton
   3 
   4 ob1 = MyClass()
   5 ob2 = MyClass()
   6 assert ob1 is ob2

结构型模式

Proxy(代理)

意图

为其他对象提供一种代理以控制对这个对象的访问。
ProxyPattern.gif

代码

   1 class Proxy:
   2     def __init__( self, subject ):
   3         self.__subject = subject
   4     def __getattr__( self, name ):
   5         return getattr( self.__subject, name )   

例子

   1 class RGB:
   2     def __init__( self, red, green, blue ):
   3         self.__red = red
   4         self.__green = green
   5         self.__blue = blue
   6     def Red( self ):
   7         return self.__red
   8     def Green( self ):
   9         return self.__green
  10     def Blue( self ):
  11         return self.__blue 

使用Proxy改变Blue函数:

   1 class NoBlueProxy( Proxy ):
   2     def Blue( self ):
   3         return 0

使用: >>> rgb = RGB( 100, 192, 240 )

>>> rgb.Red()

100

>>> proxy = Proxy( rgb )

>>> proxy.Green()

192

>>> noblue = NoBlueProxy( rgb )

>>> noblue.Green()

192

>>> noblue.Blue()

0

}}} 使用: >>> rgb = RGB( 100, 192, 240 )

>>> rgb.Red()

100

>>> proxy = Proxy( rgb )

>>> proxy.Green()

192

>>> noblue = NoBlueProxy( rgb )

>>> noblue.Green()

192

>>> noblue.Blue()

0

特殊说明

  • 因为在Proxy中没有setattr函数,因此只可以得到rgb中的值,但不能改变,比如可以"r = noblue._RBGred",但不能写"noblue._RBGred = 255",如果要想改变RBG中的值,只有在RBG中定义一些函数如"setBlue...",在noblue中直接调用。

  • 在Proxy中也不能定义setattr,否则在init中会发生死循环。

flyweight

意图

运用共享技术有效地支持大量细粒度的对象。

实现代码

   1 #实现过程类似于singleton模式
   2 
   3 import weakref
   4 #weekref产生的value不能保持对象存在。当对象不包括weakref在内的引用计数达到0时,对象将被删除。
   5 
   6 class Instrument(object):
   7     _InstrumentPool = weakref.WeakValueDictionary()
   8 
   9     def __new__(cls, name):
  10         '''Instrument(name)
  11         Create a new instrument object, or return an existing one'''
  12         obj = Instrument._InstrumentPool.get(name, None)
  13 
  14         if not obj:
  15             print "new",name
  16             obj = object.__new__(cls)
  17             Instrument._InstrumentPool[name] = obj
  18 
  19         return obj
  20 
  21     def __init__(self, name):
  22         '''Complete object construction'''
  23         self.name = name
  24         print "New instrument @%04x, %s" % (id(self), name)
  25 
  26         # ... connect instrument to datasource ...
  27 
  28 #测试
  29 import unittest
  30 
  31 class InstrumentTests(unittest.TestCase):
  32     def testInstrument(self):
  33         ibm1 = Instrument("IBM")
  34         ms = Instrument("MS")
  35         ibm2 = Instrument("IBM")
  36         self.assertEquals(id(ibm1), id(ibm2))
  37         self.assertNotEquals(id(ibm1), id(ms))
  38 
  39         self.assertEquals(2, len(Instrument._InstrumentPool),
  40             "Total instruments allocated")
  41 
  42         # This bit assumes CPython memory allocation:
  43         del(ibm1)
  44         del(ibm2)
  45         # 每一次调用Instrument,因其函数__new__中的Instrument._InstrumentPool[name]是weakref,只有obj = object.__new__(cls)引用一次。所以del(ibm1)和del(imb2)后引用计数达到0,对象被清理。
  46         self.assertEquals(1, len(Instrument._InstrumentPool),
  47             "Total instruments allocated")
  48 
  49 
  50 if __name__=='__main__':
  51     unittest.main()

行为模式

Chain of Responsibility(职责链)

意图

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

说明

用一系列类(classes)试图处理一个请求request,这些类之间是一个松散的耦合,唯一共同点是在他们之间传递request. 也就是说,来了一个请求,A类先处理,如果没有处理,就传递到B类处理,如果没有处理,就传递到C类处理,就这样象一个链条(chain)一样传递下去。 例如,窗口UI对消息的处理:
CORPattern.gif

代码实现

模拟UI对消息的处理

   1 class Event:
   2     def __init__( self, name ):
   3         self.name = name
   4 
   5 class Widget:
   6     def __init__( self, parent = None ):
   7         self.__parent = parent
   8     def Handle( self, event ):
   9         handler = 'Handle_' + event.name
  10         if hasattr( self, handler ):
  11             method = getattr( self, handler )
  12             method( event )
  13         elif self.__parent:
  14             self.__parent.Handle( event )
  15         elif hasattr( self, 'HandleDefault' ):
  16             self.HandleDefault( event )   

使用: 当用一个event被Handle,将调用Handle_"event.name",如果没有此函数就调用parent来处理此event,如果还没有被处理,就试着交给HandleDefault()。 例如:

   1 class MainWindow(Widget):
   2     def Handle_close( self, event ):
   3         print 'MainWindow: ' + event.name
   4     def HandleDefault( self, event ):
   5         print 'Default: ' + event.name
   6         
   7 class Button( Widget ):
   8     def Handle_click( self, event ):
   9         print 'Button: ' + event.name

Observer(观察者)

意图

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

经典应用

MFC中document类对所有view的更新,ddx/ddv对窗口上控件的更新。

代码实现

   1 class Subject:
   2     def __init__(self):
   3         self._observers = []
   4 
   5     def attach(self, observer):
   6         if not observer in self._observers:
   7             self._observers.append(observer)
   8 
   9     def detach(self, observer):
  10         try:
  11             self._observers.remove(observer)
  12         except ValueError:
  13             pass
  14 
  15     def notify(self, modifier=None):
  16         for observer in self._observers:
  17             if modifier != observer:
  18                 observer.update(self)

例子,用法

   1 # Example usage
   2 class Data(Subject):
   3     def __init__(self, name=''):
   4         Subject.__init__(self)
   5         self.name = name
   6         self.data = 0
   7 
   8     def setData(self, data):
   9         self.data = data
  10         self.notify()
  11 
  12     def getData(self):
  13         return self.data
  14 
  15 
  16 class HexViewer:
  17     def update(self, subject):
  18         print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.getData())
  19 
  20 
  21 class DecimalViewer:
  22     def update(self, subject):
  23         print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.getData())
  24 
  25 
  26 # Example usage...
  27 def main():
  28     data1 = Data('Data 1')
  29     data2 = Data('Data 2')
  30     view1 = DecimalViewer()
  31     view2 = HexViewer()
  32     data1.attach(view1)
  33     data1.attach(view2)
  34     data2.attach(view2)
  35     data2.attach(view1)
  36 
  37     print "Setting Data 1 = 10"
  38     data1.setData(10)
  39     print "Setting Data 2 = 15"
  40     data2.setData(15)
  41     print "Setting Data 1 = 3"
  42     data1.setData(3)
  43     print "Setting Data 2 = 5"
  44     data2.setData(5)
  45     print "Detach HexViewer from data1 and data2."
  46     data1.detach(view2)
  47     data2.detach(view2)
  48     print "Setting Data 1 = 10"
  49     data1.setData(10)
  50     print "Setting Data 2 = 15"
  51     data2.setData(15)

Template Method(模板方法)

意图

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

实现代码

   1 class Base:
   2     def doAll(self):
   3         self.doThis()
   4         self.doThat()
   5     
   6 class Foo(Base):
   7     def doThis(self):
   8         print "do this"
   9     def doThat(self):
  10         print "do that"
  11 
  12 #测试
  13 Foo a
  14 a.doAll()
  15 #输出
  16 #do this
  17 #do that

Visitor(访问者)

意图

作用于某个对象群中各个对象的操作. 它可以使你在不改变这些对象本身的情况下,定义作用于这些对象的新操作.

实现代码

   1 class Visitor:
   2     def __init__(self):
   3         self._methodDic={}
   4 
   5     def default(self, other):
   6         print "What's this:", other
   7 
   8     def addMethod(self, method):
   9         self._methodDic[method.getKey()]=method
  10 
  11     def __call__(self, other):
  12         method=self._methodDic.get(\
  13                 other.__class__.__name__,self.default)
  14         return method(other)

用法、例子

MyVisit的函数call中定义对target的具体访问操作。

   1 class MyVisit:
   2     """
   3     Instead of deriving from Visitor the work is
   4     done by instances with this interface.
   5     """
   6     def __init__(self, otherClass):
   7         self._msg='Visit: %s'%otherClass.__name__
   8         self._key=otherClass.__name__
   9 
  10     def __call__(self, target):
  11         print self._msg, target
  12 
  13     def getKey(self):
  14         return self._key
  15 
  16 # 被访问者
  17 class E1:pass
  18 class E2:pass
  19 class E3:pass
  20 
  21 # 用法
  22 
  23 collection=[E1(), E1(), E2(), E3()]
  24 
  25 visitor=Visitor()
  26 visitor.addMethod(MyVisit(E1))
  27 visitor.addMethod(MyVisit(E2))
  28 
  29 map(visitor, collection)

输出:

Visit: E1 <main.E1 instance at 7ff6d0>

Visit: E1 <main.E1 instance at 7ff730>

Visit: E2 <main.E2 instance at 7ff780>

What's this: <main.E3 instance at 7ff7b0>

# 简化用法

   1 visitor = Visitor()
   2 visitor.addMethod(MyVisit(E1))
   3 a = E1()
   4 visitor(a)

输出:

Visit: E1 <main.E1 instance at 0x00A91EE0>

Command(命令)

意图

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。在python中叫“Command Dispatch Pattern”,也不需要将请求封装成对象,直接用字符串作命令请求。

实现代码

   1 class Dispatcher:
   2 
   3     def do_get(self):
   4             print("do_get")
   5 
   6     def do_put(self):
   7             print("d0_put")
   8                         
   9     def error(self):
  10             print("error")
  11 
  12     def dispatch(self, command):
  13         mname = 'do_' + command
  14         if hasattr(self, mname):
  15             method = getattr(self, mname)
  16             method()
  17         else:
  18             self.error()

用法

   1 Dispatcher a
   2 a.dispatch("get")
   3 a.dispatch("put")

state(代理)

意图

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。

实现代码

   1 class NetworkCardState:
   2     """Abstract State Object"""
   3     def send(self):
   4         raise "NetworkCardState.send - not overwritten"
   5     
   6     def receive(self):
   7         raise "NetworkCardState.receive - not overwritten"
   8 
   9     
  10 class Online(NetworkCardState):
  11     """Online state for NetworkCard"""
  12     def send(self):
  13         print "sending Data"
  14         
  15     def receive(self):
  16         print "receiving Data"
  17 
  18 
  19 class Offline(NetworkCardState):
  20     """Offline state for NetworkCard"""
  21     def send(self):
  22         print "cannot send...Offline"
  23         
  24     def receive(self):
  25         print "cannot receive...Offline"
  26 
  27     
  28 class NetworkCard:
  29     def __init__(self):
  30         self.online = Online()
  31         self.offline = Offline()
  32         ##default state is Offline
  33         self.currentState = self.offline 
  34     
  35     def startConnection(self):
  36         self.currentState = self.online
  37 
  38     def stopConnection(self):
  39         self.currentState = self.offline
  40     
  41     def send(self):
  42         self.currentState.send()
  43         
  44     def receive(self):
  45         self.currentState.receive()
  46         
  47 
  48 def main():
  49     myNetworkCard = NetworkCard()
  50     print "without connection:"
  51     myNetworkCard.send()
  52     myNetworkCard.receive()
  53     print "starting connection"
  54     myNetworkCard.startConnection()
  55     myNetworkCard.send()
  56     myNetworkCard.receive()
  57 
  58 if __name__ == '__main__':
  59     main()

interpreter(解释器)

意图

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示 来解释语言中的句子。

designpattern (last edited 2009-12-25 07:10:09 by localhost)