Featured image of post 设计模式

设计模式

浅喜似苍狗,深爱如长风

MVC模式

MVC 模式代表 Model-View-Controller(模型-视图-控制器) 模式。这种模式用于应用程序的分层开发。

  • Model(模型) - 模型代表一个存取数据的对象或 JAVA POJO。它也可以带有逻辑,在数据变化时更新控制器。
  • View(视图) - 视图代表模型包含的数据的可视化。
  • Controller(控制器) - 控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。

alt text

概要

  • 目的:关注点分离

  • 模型:模型的任务是管理数据。不论数据是来自数据库、API 还是 JSON 对象,模型都要负责管理它们。

  • 视图:负责显示数据(模型)的用户界面,不包含业务逻辑。

  • 控制器:它充当视图和模型之间的中介。 它监听由视图触发的事件并查询相同的模型。

  • 实例:用户通过浏览器(视图)发送请求,服务器端的控制器处理请求,模型进行数据处理。

当开发大型应用程序,需要清晰分离数据、业务逻辑和用户界面时,考虑使用MVC模式。

代码

  • Model.py
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
import json

class Person(object):
    def __init__(self, first_name = None, last_name = None):
        self.first_name = first_name
        self.last_name = last_name
    #returns Person name, ex: John Doe
    def name(self):
        return ("%s %s" % (self.first_name,self.last_name))

    @classmethod
    #returns all people inside db.txt as list of Person objects
    def getAll(self):
        database = open('db.txt', 'r')
        result = []
        json_list = json.loads(database.read())
        for item in json_list:
            item = json.loads(item)
            person = Person(item['first_name'], item['last_name'])
            result.append(person)
        return result
  • 视图 它显示模型中获取的所有记录。 视图从不与模型交互; 控制器完成这项工作(与模型和视图通信)。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from model import Person
def showAllView(list):
    print 'In our db we have %i users. Here they are:' % len(list)
    for item in list:
        print item.name()

def startView():
   print 'MVC - the simplest example'
   print 'Do you want to see everyone in my db?[y/n]'

def endView():
   print 'Goodbye!'
  • 控制器 控制器通过 getAll() 方法与模型交互,该方法获取显示给最终用户的所有记录。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
from model import Person
import view

def showAll():
    people_in_db = Person.getAll()
    return view.showAllView(people_in_db)

def start():
    view.startView()
    input = raw_input()
    if input == 'y':
        return showAll()
    else:
        return view.endView()

if __name__ == "__main__":
   #running controller function
   start()

单例模式

单例模式(Singleton pattern)将类的实例化限制为一个对象。 它是一种创建模式,只涉及一个类来创建方法和指定的对象。 这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。 单例模式是一种创建型设计模式,它确保一个类只有一个实例,并提供了一个全局访问点来访问该实例。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
class Singleton:
    __instance = None
    @staticmethod
    def getInstance():
        if Singleton.__instance == None:
            Singleton()
        return Singleton.__instance
    def __init__(self):
        if Singleton.__instance != None:
            raise Exception("This class is a singleton!")
        else:
            Singleton.__instance = self

s = Singleton()
print s

s = Singleton.getInstance()
print s

s = Singleton.getInstance()
print s

工厂模式

工厂模式(Factory Pattern)属于创建模式列表类别。 它提供了创建对象的最佳方式之一。 在工厂模式中,创建对象时不会向客户端公开逻辑并使用公共接口引用新创建的对象。

它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。

工厂模式是使用工厂方法在 Python 中实现的。 当用户调用一个方法时,我们传入一个字符串并将返回值作为一个新对象通过工厂方法实现。 工厂方法中使用的对象类型由方法传递的字符串决定。

通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

概要

  • 意图:定义一个创建对象的接口,让其子类决定实例化哪一个具体的类。工厂模式使对象的创建过程延迟到子类。

  • 何时使用:当我们需要在不同条件下创建不同实例时。

  • 如何解决:通过让子类实现工厂接口,返回一个抽象的产品。

  • 缺点:每次增加一个产品时,都需要增加一个具体类和对应的工厂,使系统中类的数量成倍增加,增加了系统的复杂度和具体类的依赖。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Button(object):
    html = ""
    def get_html(self):
        return self.html

class Image(BUttton):
    html = "<img></img>"

class Input(Button):
    html = "<input></input>"

class Flash(Button):
    html = "<obj></obj>"

class ButtonFactory():
    def create_button(self,typ):
        targetclass = typ.capitalize()
        return globals()[targetclass]()
    
button_obj = ButtonFactory()
button = ['image', 'input', 'flash']
for b in button:
    print button_obi.create_button(b).get_html()

这段代码展示了如何使用工厂模式创建不同类型的按钮对象。通过定义一个基类 Button 和多个子类 Image、Input、Flash,以及一个工厂类 ButtonFactory,可以根据传入的类型动态创建相应的按钮对象,并获取其 HTML 表示。

建造者模式

建造者模式(Builder Pattern)是一种独特的设计模式,它有助于使用简单的对象构建复杂的对象并使用算法方法。 这种设计模式属于创建模式的范畴。 在这种设计模式中,构建器类逐步构建最终对象。 此构建器独立于其他对象。

概要

  • 产品(Product):要构建的复杂对象。产品类通常包含多个部分或属性。

  • 抽象建造者(Builder):定义了构建产品的抽象接口,包括构建产品的各个部分的方法。

  • 具体建造者(Concrete Builder):实现抽象建造者接口,具体确定如何构建产品的各个部分,并负责返回最终构建的产品。

  • 指导者(Director):负责调用建造者的方法来构建产品,指导者并不了解具体的构建过程,只关心产品的构建顺序和方式。

  • 意图:将一个复杂的构建过程与其表示相分离,使得同样的构建过程可以创建不同的表示。

  • 主要解决:在软件系统中,一个复杂对象的创建通常由多个部分组成,这些部分的组合经常变化,但组合的算法相对稳定。

  • 实例:去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出不同的"套餐"。

  • 如何解决:将变与不变的部分分离开。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
class Director:
    __builder = None

    def setBuilder(self,builder):
        self.__builder = builder

    def getCar(self):
        car = Car()

        body = self.__builder.getBody()
        car.setBody(body)

        engine = self.__builder.getEngine()
        car.setEngine(engine)

        i = 0
        while i < 4:
            wheel = self.__builder.getWheel()
            car.attachWeel(wheel)
            i += 1
        return car

class Car:
    def __init__(self):
        self.__wheels = list()
        self.__engine = None
        self.__body = None

    def setBody(self, body):
        self.__body = body

    def attachWheel(self, wheel):
        self.__wheels.append(wheel)

    def setEngine(self, engine):
        self.__engine = engine

    def specification(self):
        print "body: %s" % self.__body.shape
        print "engine horsepower: %d" % self.__engine.horsepower
        print "tire size: %d\'" % self.__wheels[0].size

class Builder:
    def getWheel(self): pass
    def getEngine(self): pass
    def getBody(self): pass

class JeepBuilder(Builder):

    def getWheel(self):
        wheel = Wheel()
        wheel.size = 22
        return wheel

    def getEngine(self):
        engine = Engine()
        engine.horsepower = 400
        return engine

    def getBody(self):
        body = Body()
        body.shape = "SUV"
        return body 

class Wheel:
    size = None

class Engine:
    horsepower = None

class Body:
    shape = None

def main():
    jeepBuilder = JeepBuilder()

    director = Director()

    print "Jeep"
    director.setBuilder(jeepBuilder)
    jeep = director.getCar()
    jeep.specification()
    print "" 

if __name__ == "__main__":
    main()      

原型模式

原型模式(Prototype Pattern)有助于隐藏由类创建的实例的复杂性。 现有对象的概念与从头开始创建的新对象的概念不同。

如果需要,新复制的对象可能会在属性上进行一些更改。 这种方法可以节省用于产品开发的时间和资源。

概要

  • 意图:使用原型实例指定要创建对象的种类,并通过拷贝这些原型创建新的对象

  • 主要解决:在运行时动态建立和删除原型。

  • 如何解决:通过已有的一个原型对象,快速生成与原型对象相同的实例。

  • 注意事项:与直接实例化类创建新对象不同,原型模式通过拷贝现有对象生成新对象。浅拷贝通过实现 Cloneable 实现,深拷贝通过实现 Serializable 读取二进制流实现。

  • 原型接口(Prototype Interface):定义一个用于克隆自身的接口,通常包括一个 clone() 方法。

  • 具体原型类(Concrete Prototype):实现原型接口的具体类,负责实际的克隆操作。这个类需要实现 clone() 方法,通常使用浅拷贝或深拷贝来复制自身。

  • 客户端(Client):使用原型实例来创建新的对象。客户端调用原型对象的 clone() 方法来创建新的对象,而不是直接使用构造函数。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import copy

class Prototype:
    _type = None
    _value = None

    def clone(self):
        pass 

    def getType(self):
        return self._type

    def getValue(self):
        return self._value

class Type1(Prototype):

    def __init__(self,number):
        self._type = "Type1"
        self._value = number

    def clone(self):
        return copy.copy(self)

class Type2(Prototype):

   """ Concrete prototype. """

   def __init__(self, number):
      self._type = "Type2"
      self._value = number

   def clone(self):
      return copy.copy(self)       

class ObjectFactory:

    __type1Value1 = None
    __type1Value2 = None
    __type2Value1 = None
    __type2Value2 = None

    @staticmethod
    def initialize():
        ObjectFactory.__type1Value1 = Type1(1)
        ObjectFactory.__type1Value2 = Type1(2)
        ObjectFactory.__type2Value1 = Type2(1)
        ObjectFactory.__type2Value2 = Type2(2)

    @staticmethod
    def getType1Value1():
        return ObjectFactory.__type1Value1.clone()

    @staticmethod
    def getType1Value2():
        return ObjectFactory.__type1Value2.clone()

    @staticmethod
    def getType2Value1():
        return ObjectFactory.__type2Value1.clone()

    @staticmethod
    def getType2Value2():
        return ObjectFactory.__type2Value2.clone()

def main():
    ObjectFactory.initialize()

    instance = ObjectFactory.getType1Value1()
    print "%s: %s" % (instance.getType(), instance.getValue())

    instance = ObjectFactory.getType1Value2()
    print "%s: %s" % (instance.getType(), instance.getValue())
   
    instance = ObjectFactory.getType2Value1()
    print "%s: %s" % (instance.getType(), instance.getValue())
   
    instance = ObjectFactory.getType2Value2()
    print "%s: %s" % (instance.getType(), instance.getValue())

if __name__ == "__main__":
    main()

外观模式

外观模式(Facade Pattern)为子系统中的一组接口提供统一的接口。 它定义了一个任何子系统都可以使用的更高级别的接口。

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

概要

  • 意图:为一个复杂的子系统提供一个一致的高层接口。这样,客户端代码就可以通过这个简化的接口与子系统交互,而不需要了解子系统内部的复杂性。

  • 外观(Facade):提供一个简化的接口,封装了系统的复杂性。外观模式的客户端通过与外观对象交互,而无需直接与系统的各个组件打交道

  • 子系统(Subsystem):由多个相互关联的类组成,负责系统的具体功能。外观对象通过调用这些子系统来完成客户端的请求。

  • 客户端(Client):使用外观对象来与系统交互,而不需要了解系统内部的具体实现。

代码:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
class _IgnitionSystem(object):

    @staticmethod
    def produce_spark():
        return True

class _Engine(object):

    def __init__(self):
        self.revs_per_minute = 0

    def turnon(self):
        self.revs_per_minute = 2000

    def turnoff(self):
        self.revs_per_minute = 0

class _FuelTank(object):

    def __init__(self,level=30):
        self._level = level

    @property
    def level(self):
        return self._level

    @level.setter
    def level(self,level):
        self._level = level

class _DashBoardLight(object):

    def __init__(self, is_on=False):
        self._is_on = is_on

    def __str__(self):
        return self.__class__.__name__

    @property
    def is_on(self):
        return self._is_on

    @is_on.setter
    def is_on(self, status):
        self._is_on = status

    def status_check(self):
        if self._is_on:
            print("{}: ON".format(str(self)))
        else:
            print("{}: OFF".format(str(self)))

class _HandBrakeLight(_DashBoardLight):
    pass

class _FogLampLight(_DashBoardLight):
    pass

class _Dashboard(object):
   
    def __init__(self):
       self.lights = {"handbreak": _HandBrakeLight(), "fog": _FogLampLight()}
   
    def show(self):
	    for light in self.lights.values():
            light.status_check()

# Facade
class Car(object):
   
    def __init__(self):
        self.ignition_system = _IgnitionSystem()
        self.engine = _Engine()
        self.fuel_tank = _FuelTank()
        self.dashboard = _Dashboard()

    @property
    def km_per_litre(self):
        return 17.0

    def consume_fuel(self, km):
        litres = min(self.fuel_tank.level, km / self.km_per_litre)
        self.fuel_tank.level -= litres

    def start(self):
        print("\nStarting...")
        self.dashboard.show()
        if self.ignition_system.produce_spark():
            self.engine.turnon()
        else:
            print("Can't start. Faulty ignition system")

    def has_enough_fuel(self, km, km_per_litre):
        litres_needed = km / km_per_litre
        if self.fuel_tank.level > litres_needed:
            return True
        else:
            return False
        
        def drive(self, km = 100):
            print("\n")
            if self.engine.revs_per_minute > 0:
            while self.has_enough_fuel(km, self.km_per_litre):
                self.consume_fuel(km)
                print("Drove {}km".format(km))
                print("{:.2f}l of fuel still left".format(self.fuel_tank.level))
            else:
            print("Can't drive. The Engine is turned off!")
            
            def park(self):
            print("\nParking...")
            self.dashboard.lights["handbreak"].is_on = True
            self.dashboard.show()
            self.engine.turnoff()
            
            def switch_fog_lights(self, status):
            print("\nSwitching {} fog lights...".format(status))
            boolean = True if status == "ON" else False
            self.dashboard.lights["fog"].is_on = boolean
            self.dashboard.show()
            
            def fill_up_tank(self):
            print("\nFuel tank filled up!")
            self.fuel_tank.level = 100

class CarFacade:
    def __init__(self):
        self.car = Car()
    
    def start_car(self):
        self.car.start()
    
    def drive_car(self, km=100):
        self.car.drive(km)
    
    def park_car(self):
        self.car.park()
    
    def fill_fuel(self):
        self.car.fill_up_tank()
        
    def switch_fog_lights(self, status):
        self.car.switch_fog_lights(status)
				
# the main function is the Client
def main():
    car_facade = CarFacade()
    car_facade.start_car()
    car_facade.drive_car(100)
    car_facade.switch_fog_lights("ON")
    car_facade.park_car()
    car_facade.fill_fuel()
    car_facade.start_car()
    car_facade.drive_car(50)

if __name__ == "__main__":
    main()

命令模式

命令模式(Command Pattern)在动作之间添加了一个抽象级别,并包含一个调用这些动作的对象。

在此设计模式中,客户端创建一个命令对象,其中包含要执行的命令列表。 创建的命令对象实现特定接口。

在软件系统中,“行为请求者"与"行为实现者"通常呈现一种"紧耦合”。但在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,实现二者之间的松耦合。这就是命令模式(Command Pattern)。

概要

  • 意图:将请求封装为一个对象,允许用户使用不同的请求对客户端进行参数化。

  • 解决的问题:解决在软件系统中请求者和执行者之间的紧耦合问题,特别是在需要对行为进行记录、撤销/重做或事务处理等场景。

  • 接收者(Receiver):执行命令的实际对象,知道如何执行与请求相关的操作,实际执行命令的对象。

  • 命令(Command):定义执行命令的接口。定义了执行操作的接口,通常包含一个 execute 方法,用于调用具体的操作。

  • 具体命令(ConcreteCommand):实现了命令接口,负责执行具体的操作。它通常包含了对接收者的引用,通过调用接收者的方法来完成请求的处理。

  • 调用者(Invoker):发送命令的对象,它包含了一个命令对象并能触发命令的执行。调用者并不直接处理请求,而是通过将请求传递给命令对象来实现。

  • 客户端(Client):创建具体命令对象并设置其接收者,将命令对象交给调用者执行。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
def demo(a,b,c):
    print 'a:',a
    print 'b:',b
    print 'c:',c

class Command:
    def __init__(self, cmd, *args):
       self._cmd=cmd
       self._args=args

    def __call__(self, *args):
       return apply(self._cmd, self._args+args)
cmd = Command(dir,__builtins__)
print cmd()

cmd = Command(demo,1,2)
cmd(3)

适配器模式

适配器模式(Adapter pattern)充当两个不兼容接口之间的桥梁。 这种类型的设计模式属于结构模式,因为这种模式结合了两个独立接口的能力。

此模式涉及单个类,负责连接独立或不兼容接口的功能。 现实生活中的例子可能是读卡器,它充当存储卡和笔记本电脑之间的适配器。 将存储卡插入读卡器,将读卡器插入笔记本电脑,这样就可以通过笔记本电脑读取存储卡。

适配器设计模式有助于让类协同工作。 它根据需要将一个类的接口转换为另一个接口。 该模式包括一个物种形成和多态性,它命名一个名称和多个形式。 假设可以根据收集的要求使用形状类。

适配器模式有两种类型

  • 对象适配器模式:这种设计模式依赖于对象实现。 因此,它被称为对象适配器模式。

  • 类适配器模式:这是实现适配器设计模式的另一种方式。 该模式可以使用多重继承来实现。

概要

  • 目标接口(Target):定义客户需要的接口。

  • 适配者类(Adaptee):定义一个已经存在的接口,这个接口需要适配。

  • 适配器类(Adapter):实现目标接口,并通过组合或继承的方式调用适配者类中的方法,从而实现目标接口。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class EuropeanSocketInterface:
    def voltage(self): pass

    def live(self): pass
    def neutral(self): pass
    def earth(self): pass

# Adaptee
class Socket(EuropeanSocketInterface):
    def voltage(self):
        return 230

    def live(self):
        return 1

    def neutral(self):
        return -1

    def earth(self):
        return 0

# Target interface
class USASocketInterface:
    def voltage(self): pass
    def live(self): pass
    def neutral(self): pass

# The Adapter
class Adapter(USASocketInterface):
    __socket = None
    def __init__(self, socket):
        self.__socket = socket

    def voltage(self):
        return 110

    def live(self):
        return self.__socket.live()

    def neutral(self):
        return self.__socket.neutral()

# Client
class ElectricKettle:
    __power = None

    def __init__(self, power):
        self.__power = power

    def boil(self):
        if self.__power.voltage() > 110:
            print "Kettle on fire!"
        else:
            if self.__power.live() == 1 and \
            self.__power.neutral() == -1:
            print "Coffee time!"
            else:
            print "No power."

def main():
    # Plug in 
    socket = Socket()
    adapter = Adapter(socket)
    kettle = ElectricKettle(adapter)

    # Make coffee
    kettle.boil()

    return 0

if __name__ == "__main__":
    main()

装饰器模式

装饰器模式(Decorator Pattern)允许用户在不改变其结构的情况下向现有对象添加新功能。 这种类型的设计模式属于结构模式,因为这种模式充当现有类的包装器。

这个模式创建了一个装饰器类,它包装了原始类并提供了额外的功能来保持类方法签名的完整性。

装饰器模式的动机是动态地附加对象的附加职责。

代码

以下代码简单演示了如何在Python中实现装饰器设计模式。 该插图涉及以类形式展示一家咖啡店。 创建的咖啡类是一个抽象类,这意味着它不能被实例化。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import six
from abc import ABCMeta

@six.add_metaclass(ABCMeta)
class Abstract_Coffee(object):

    def get_cost(self):
        pass

    def get_ingredients(self):
        pass

    def get_tax(self):
        return 0.1*self.get_cost()

class Concrete_Coffee(Abstract_Coffee):

    def get_cost(self):
        return 1.00

    def get_ingredients(self):
        return 'coffee'

@six.add_metaclass(ABCMeta)
class Abstract_Coffee_Decorator(Abstract_Coffee):

    def __init__(self,decorated_coffee):
        self.decorated_coffee = decorated_coffee

    def get_cost(self):
        return self.decorated_coffee.get_cost()

    def get_ingredients(self):
        return self.decorated_coffee.get_ingredients()

class Sugar(Abstract_Coffee_Decorator):

    def __init__(self,decorated_coffee):
        Abstract_Coffee_Decorator.__init__(self,decorated_coffee)

    def get_cost(self):
        return self.decorated_coffee.get_cost()

    def get_ingredients(self):
        return self.decorated_coffee.get_ingredients() + ', sugar'

class Milk(Abstract_Coffee_Decorator):

    def __init__(self,decorated_coffee):
        Abstract_Coffee_Decorator.__init__(self,decorated_coffee)

    def get_cost(self):
        return self.decorated_coffee.get_cost() + 0.25

    def get_ingredients(self):
        return self.decorated_coffee.get_ingredients() + ', milk'

class Vanilla(Abstract_Coffee_Decorator):

    def __init__(self,decorated_coffee):
        Abstract_Coffee_Decorator.__init__(self,decorated_coffee)

    def get_cost(self):
        return self.decorated_coffee.get_cost() + 0.75

    def get_ingredients(self):
        return self.decorated_coffee.get_ingredients() + ', vanilla'

代理模式

代理模式(Proxy Pattern)包含一个称为"Proxy"代理的新对象,以代替称为"真实主体"的现有对象。 真实主体创建的代理对象必须在同一接口上,这样客户端就不会知道代理被用来代替真实对象。 客户端向代理产生的请求通过真实主体传递。代理模式(Proxy Pattern)包含一个称为"Proxy"代理的新对象,以代替称为"真实主体"的现有对象。 真实主体创建的代理对象必须在同一接口上,这样客户端就不会知道代理被用来代替真实对象。 客户端向代理产生的请求通过真实主体传递。

在代理模式(Proxy Pattern)中,一个类代表另一个类的功能,这种类型的设计模式属于结构型模式。

代理模式通过引入一个代理对象来控制对原对象的访问。代理对象在客户端和目标对象之间充当中介,负责将客户端的请求转发给目标对象,同时可以在转发请求前后进行额外的处理。

在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

概要

  • 增加中间层:创建一个代理类,作为真实对象的中间层。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Image:
    def __init__(self,filename):
        self._filename = filename

    def load_image_from_disk( self ):
        print("loading " + self._filename )
   
    def display_image( self ):
        print("display " + self._filename)


class Proxy:
    def __init__( self, subject ):
        self._subject = subject
        self._proxystate = None

class ProxyImage(Proxy):
    def display_image( self ):
        if self._proxystate == None:
            self._subject.load_image_from_disk()
            self._proxystate = 1
        print("display " + self._subject._filename )

proxy_image1 = ProxyImage( Image("HiRes_10Mb_Photo1") )
proxy_image2 = ProxyImage( Image("HiRes_10Mb_Photo2") )

proxy_image1.display_image() # loading necessary
proxy_image1.display_image() # loading unnecessary
proxy_image2.display_image() # loading necessary
proxy_image2.display_image() # loading unnecessary
proxy_image1.display_image() # loading unnecessary

责任链模式

责任链模式(Chain of Responsibility)是一种设计模式。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。

责任链模式用于在软件中实现松散耦合,其中来自客户端的指定请求通过包含在其中的对象链传递。 它有助于构建对象链。 请求从一端进入,从一个对象移动到另一个对象。

此模式允许对象在不知道哪个对象将处理请求的情况下发送命令。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
class ReportFormat(object):
    PDF = 0
    TEXT = 1

class Report(object):
    def __init__(self, format_):
        self.title = 'Monthly report'
        self.text = ['Things are going', 'really, really well.']
        self.format_ = format_

class Handler(object):
    def __init__(self):
        self.nextHandler = None

    def handle(self, request):
        self.nextHandler.handle(request)

class PDFHandler(Handler):

    def handle(self, request):
        if request.format_ == ReportFormat.PDF:
            self.output_report(request.title, request.text)
        else:
            super(PDFHandler, self).handle(request)
	
    def output_report(self, title, text):
        print '<html>'
        print ' <head>'
        print ' <title>%s</title>' % title
        print ' </head>'
        print ' <body>'
        for line in text:
            print ' <p>%s ' % line
        print ' </body>'
        print '</html>'

class TextHandler(Handler):
   
    def handle(self, request):
        if request.format_ == ReportFormat.TEXT:
            self.output_report(request.title, request.text)
        else:
            super(TextHandler, self).handle(request)
   
    def output_report(self, title, text):
        print 5*'*' + title + 5*'*'
        for line in text:
            print line

class ErrorHandler(Handler):
    def handle(self, request):
        print "Invalid request"

if __name__ == '__main__':
    report = Report(ReportFormat.TEXT)
    pdf_handler = PDFHandler()
    text_handler = TextHandler()

    pdf_handler.nextHandler = text_handler
    text_handler.nextHandler = ErrorHandler()
    pdf_handler.handle(report)

观察者模式

在观察者模式(Observer Pattern)中,对象表示为等待事件触发的观察者。 一旦指定的事件发生,观察者就会附加到主题上。 当事件发生时,主体告诉观察者它已经发生。

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

概要

  • 实例:拍卖系统:拍卖师作为主题,竞价者作为观察者,拍卖价格更新时通知所有竞价者。

  • 主题(Subject):也称为被观察者或可观察者,它是具有状态的对象,并维护着一个观察者列表。主题提供了添加、删除和通知观察者的方法。

  • 观察者(Observer):观察者是接收主题通知的对象。观察者需要实现一个更新方法,当收到主题的通知时,调用该方法进行更新操作

  • 具体主题(Concrete Subject):具体主题是主题的具体实现类。它维护着观察者列表,并在状态发生改变时通知观察者

  • 具体观察者(Concrete Observer):具体观察者是观察者的具体实现类。它实现了更新方法,定义了在收到主题通知时需要执行的具体操作。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
import threading
import time

class Subject:
    def __init__(self):
        self._observers = []

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

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

    def notify(self, message):
        for observer in self._observers:
            observer.update(message)

class Downloader(threading.Thread, Subject):
    def __init__(self):
        threading.Thread.__init__(self)
        Subject.__init__(self)
        self.i = 0

    def run(self):
        print('downloading')
        for i in range(1, 5):
            self.i = i
            time.sleep(2)
            print('unfunf')
            self.notify(f'Download progress: {self.i}')
        self.notify('Download complete')
        print('hello world')

class Observer:
    def update(self, message):
        pass

class Worker(threading.Thread, Observer):
    def __init__(self, subject):
        threading.Thread.__init__(self)
        self.subject = subject
        self.subject.attach(self)

    def run(self):
        for i in range(1, 5):
            print(f'worker running: {i} ({self.subject.i})')
            time.sleep(1)
        self.subject.detach(self)
        print('done')

    def update(self, message):
        print(f'Worker received update: {message}')

t = Downloader()
t.start()

time.sleep(1)

t1 = Worker(t)
t1.start()

t2 = Worker(t)
t2.start()

t3 = Worker(t)
t3.start()

状态模式

它为状态机提供了一个模块,该模块使用子类来实现,由指定的状态机类派生。这些方法是独立于状态的,并引起使用装饰器声明的转换。

在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

状态模式允许对象在内部状态改变时改变其行为,使得对象在不同的状态下有不同的行为表现。通过将每个状态封装成独立的类,可以避免使用大量的条件语句来实现状态切换。

概要

  • 意图: 允许一个对象在其内部状态改变时改变其行为,看起来就像是改变了其类一样。

  • 实例:篮球运动员状态:运动员可以有正常、不正常和超常等状态。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
class ComputerState(object):

    name = "state"
    allowed = []

    def switch(self, state):
        """ Switch to new state """
        if state.name in self.allowed:
            print 'Current:',self,' => switched to new state',state.name
            self.__class__ = state
        else:
            print 'Current:',self,' => switching to',state.name,'not possible.'

    def __str__(self):
        return self.name

class Off(ComputerState):
    name = "off"
    allowed = ['on']

class On(ComputerState):
   """ State of being powered on and working """
    name = "on"
    allowed = ['off','suspend','hibernate']

class Suspend(ComputerState):
   """ State of being in suspended mode after switched on """
    name = "suspend"
    allowed = ['on']

class Hibernate(ComputerState):
   """ State of being in hibernation after powered on """
    name = "hibernate"
    allowed = ['on']

class Computer(object):
   """ A class representing a computer """
   
    def __init__(self, model='HP'):
        self.model = model
        # State of the computer - default is off.
        self.state = Off()
    
    def change(self, state):
        """ Change state """
        self.state.switch(state)

if __name__ == "__main__":
    comp = Computer()
    comp.change(On)
    comp.change(Off)
    comp.change(On)
    comp.change(Suspend)
    comp.change(Hibernate)
    comp.change(On)
    comp.change(Off)

策略模式

策略模式(Strategy Pattern)是一种行为模式。 策略模式的主要目标是使客户能够选择不同的算法或程序来完成指定的任务。 不同的算法可以换入和换出,而不会为上述任务带来任何复杂性。

概要

  • 意图:将每个算法封装起来,使它们可以互换使用。

  • 实例:旅行方式选择:骑自行车、坐汽车等,每种方式都是一个可替换的策略。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import types

class StrategyExample:
    def __init__(self, func = None):
        self.name = 'Strategy Example 0'
        if func is not None:
           self.execute = types.MethodType(func, self)

    def execute(self):
        print(self.name)

def execute_replacement1(self): 
    print(self.name + 'from execute 1')

def execute_replacement2(self):
    print(self.name + 'from execute 2')

if __name__ == '__main__':
    strat0 = StrategyExample()
    strat1 = StrategyExample(execute_replacement1)
    strat1.name = 'Strategy Example 1'
    strat2 = StrategyExample(execute_replacement2)
    strat2.name = 'Strategy Example 2'
    strat0.execute()
    strat1.execute()
    strat2.execute()

模板模式

模板模式(Template Pattern)使用抽象操作在基类中定义基本算法,其中子类覆盖具体行为。 模板模式将算法的轮廓保存在一个单独的方法中。 此方法称为模板方法 以下是模板模式的不同特点

  • 它定义了算法在操作中的骨架
  • 它包括重新定义算法某些步骤的子类。

概要

  • 意图:在父类中定义了算法的骨架,并允许子类在不改变算法结构的前提下重定义算法的某些特定步骤。

  • 实例:地基、走线、水管等步骤相同,后期建筑如加壁橱、栅栏等步骤不同。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class MakeMeal:

    def prepare(self): pass
    def cook(self): pass
    def eat(self): pass

    def go(self):
        self.prepare()
        self.cook()
        self.eat()

class MakePizza(MakeMeal):
    def prepare(self):
        print "Prepare Pizza"
   
    def cook(self):
        print "Cook Pizza"
   
    def eat(self):
        print "Eat Pizza"

class MakeTea(MakeMeal):
    def prepare(self):
        print "Prepare Tea"
	
    def cook(self):
        print "Cook Tea"
   
    def eat(self):
        print "Eat Tea"

makePizza = MakePizza()
makePizza.go()

print 25*"+"

makeTea = MakeTea()
makeTea.go()

享元模式

享元模式(Flyweight Pattern)属于结构设计模式类别。 它提供了一种减少对象数量的方法。 它包括有助于改进应用程序结构的各种功能。 享元对象最重要的特征是不可变的。 这意味着它们一旦构造就无法修改。 该模式使用 HashMap 来存储引用对象。

享元模式是一种软件设计模式。它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件。通常物件中的部分状态是可以分享。常见做法是把它们放在外部数据结构,当需要使用时再将它们传递给享元。

概要

  • 意图:通过共享对象来减少创建大量相似对象时的内存消耗。

  • 实例:数据库连接池:数据库连接被复用,避免频繁创建和销毁连接。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class ComplexGenetics(object):
    def __init__(self):
        pass
   
    def genes(self, gene_code):
        return "ComplexPatter[%s]TooHugeinSize" % (gene_code)

class Families(object):
    family = {}
   
    def __new__(cls, name, family_id):
        try:
            id = cls.family[family_id]
        except KeyError:
            id = object.__new__(cls)
            cls.family[family_id] = id
        return id
   
    def set_genetic_info(self, genetic_info):
        cg = ComplexGenetics()
        self.genetic_info = cg.genes(genetic_info)

    def get_genetic_info(self):
        return (self.genetic_info)

def test():
    data = (('a', 1, 'ATAG'), ('a', 2, 'AAGT'), ('b', 1, 'ATAG'))
    family_objects = []
    for i in data:
        obj = Families(i[0], i[1])
        obj.set_genetic_info(i[2])
        family_objects.append(obj)

    for i in family_objects:
        print "id = " + str(id(i))
        print i.get_genetic_info()
    print "similar id's says that they are same objects "

if __name__ == '__main__':
    test()

抽象工厂模式

抽象工厂模式(Abstract Factory Pattern)也称为工厂的工厂。

在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。

抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的创建过程解耦,使得客户端可以通过工厂接口来创建一族产品。

抽象工厂模式相对于工厂方法模式来说,就是工厂方法模式是针对一个产品系列的,而抽象工厂模式是针对多个产品系列的,即工厂方法模式是一个产品系列一个工厂类,而抽象工厂模式是多个产品系列一个工厂类。在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任丢给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责。并且当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单,而且,如果要更换这一系列的产品,则只需要更换一个工厂类即可。

如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,具体这一系列对象的创建工作由实现抽象工厂的具体工厂类来完成。

概要

  • 意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。

  • 实例:假设有不同类型的衣柜,每个衣柜(具体工厂)只能存放一类衣服(成套的具体产品),如商务装、时尚装等。每套衣服包括具体的上衣和裤子(具体产品)。所有衣柜都是衣柜类(抽象工厂)的具体实现,所有上衣和裤子分别实现上衣接口和裤子接口(抽象产品)。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
class Window:
    __toolkit = ""
    __purpose = ""

    def __init__(self, toolkit, purpose):
        self.__toolkit = toolkit
        self.__purpose = purpose

    def getToolkit(self):
        return self.__toolkit

    def getType(self):
        return self.__purpose

class GtkToolboxWindow(Window):
    def __init__(self):
        Window.__init__(self, "Gtk", "ToolboxWindow")

class GtkLayersWindow(Window):
    def __init__(self):
        Window.__init__(self, "Gtk", "LayersWindow")

class GtkMainWindow(Window):
    def __init__(self):
        Window.__init__(self, "Gtk", "MainWindow")

class QtToolboxWindow(Window):
    def __init__(self):
        Window.__init__(self, "Qt", "ToolboxWindow")

class QtLayersWindow(Window):
    def __init__(self):
        Window.__init__(self, "Qt", "LayersWindow")

class QtMainWindow(Window):
    def __init__(self):
        Window.__init__(self, "Qt", "MainWindow")

# Abstract factory class
class UIFactory:
    def getToolboxWindow(self): pass
    def getLayersWindow(self): pass
    def getMainWindow(self): pass

class GtkUIFactory(UIFactory):
    def getToolboxWindow(self):
        return GtkToolboxWindow()
    def getLayersWindow(self):
        return GtkLayersWindow()
    def getMainWindow(self):
        return GtkMainWindow()

class QtUIFactory(UIFactory):
    def getToolboxWindow(self):
        return QtToolboxWindow()
    def getLayersWindow(self):
        return QtLayersWindow()
    def getMainWindow(self):
        return QtMainWindow()

if __name__ == "__main__":
    gnome = True
    kde = not gnome

    if gnome:
        ui = GtkUIFactory()
    elif kde:
        ui = QtUIFactory()

    toolbox = ui.getToolboxWindow()
    layers = ui.getLayersWindow()
    main = ui.getMainWindow()

    print "%s:%s" % (toolbox.getToolkit(), toolbox.getType())
    print "%s:%s" % (layers.getToolkit(), layers.getType())
    print "%s:%s" % (main.getToolkit(), main.getType())

面向对象模式

迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import time 

def fib():
    a,b=0,1
    while True:
        yield b 
        a,b=b,a+b

g = fib()

try:
    for e in g:
        print(e)
        time.sleep(1)

except KeyboardInterrupt:
    print("Calculation stopped")
最后更新于 Oct 27, 2024 23:29 CST
comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计