[学习笔记] - 设计模式

简单记录,以防忘记

观察者模式

  • 使用场景:当一个对象更新,其他n个对象也需要执行某种操作的时候使用
  • 例子:UI界面,事件
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
"""
Define a one-to-many dependency between objects so that when one object
changes state, all its dependents are notified and updatedautomatically.
"""

import abc


class Subject:
"""
Know its observers. Any number of Observer objects may observe a
subject.
Send a notification to its observers when its state changes.
"""

def __init__(self):
self._observers = set()
self._subject_state = None

def attach(self, observer):
observer._subject = self
self._observers.add(observer)

def detach(self, observer):
observer._subject = None
self._observers.discard(observer)

def _notify(self):
for observer in self._observers:
observer.update(self._subject_state)

@property
def subject_state(self):
return self._subject_state

@subject_state.setter
def subject_state(self, arg):
self._subject_state = arg
self._notify()


class Observer(metaclass=abc.ABCMeta):
"""
Define an updating interface for objects that should be notified of
changes in a subject.
"""

def __init__(self):
self._subject = None
self._observer_state = None

@abc.abstractmethod
def update(self, arg):
pass


class ConcreteObserver(Observer):
"""
Implement the Observer updating interface to keep its state
consistent with the subject's.
Store state that should stay consistent with the subject's.
"""

def update(self, arg):
self._observer_state = arg
# ...


def main():
subject = Subject()
concrete_observer = ConcreteObserver()
subject.attach(concrete_observer)
subject.subject_state = 123


if __name__ == "__main__":
main()

策略模式

  • 使用场景:对不同场景有不同操作,且场景可能增加或减少
    • 但是不是场景的组合,就是你不能又骑车又开车
  • 例子:计算不同汇率,不同优惠策略,使用不同算法
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
"""
Define a family of algorithms, encapsulate each one, and make them
interchangeable. Strategy lets the algorithm vary independently from
clients that use it.
"""

import abc


class Context:
"""
Define the interface of interest to clients.
Maintain a reference to a Strategy object.
"""

def __init__(self, strategy):
self._strategy = strategy

def context_interface(self):
self._strategy.algorithm_interface()


class Strategy(metaclass=abc.ABCMeta):
"""
Declare an interface common to all supported algorithms. Context
uses this interface to call the algorithm defined by a
ConcreteStrategy.
"""

@abc.abstractmethod
def algorithm_interface(self):
pass


class ConcreteStrategyA(Strategy):
"""
Implement the algorithm using the Strategy interface.
"""

def algorithm_interface(self):
pass


class ConcreteStrategyB(Strategy):
"""
Implement the algorithm using the Strategy interface.
"""

def algorithm_interface(self):
pass


def main():
concrete_strategy_a = ConcreteStrategyA()
context = Context(concrete_strategy_a)
context.context_interface()


if __name__ == "__main__":
main()

单一职责

装饰模式

  • 使用场景:在不改变原有对象的基础之下给原有对象扩展功能,是对继承关系的一种替换方案
    • 预防类爆炸,也就是一堆类和一堆功能进行多对多关系
    • 一般用于功能的组合
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
"""
Attach additional responsibilities to an object dynamically. Decorators
provide a flexible alternative to subclassing for extending
functionality.
"""

import abc


class Component(metaclass=abc.ABCMeta):
"""
Define the interface for objects that can have responsibilities
added to them dynamically.
"""

@abc.abstractmethod
def operation(self):
pass


class Decorator(Component, metaclass=abc.ABCMeta):
"""
Maintain a reference to a Component object and define an interface
that conforms to Component's interface.
"""

def __init__(self, component):
self._component = component

@abc.abstractmethod
def operation(self):
pass


class ConcreteDecoratorA(Decorator):
"""
Add responsibilities to the component.
"""

def operation(self):
# ...
self._component.operation()
# ...


class ConcreteDecoratorB(Decorator):
"""
Add responsibilities to the component.
"""

def operation(self):
# ...
self._component.operation()
# ...


class ConcreteComponent(Component):
"""
Define an object to which additional responsibilities can be
attached.
"""

def operation(self):
pass


def main():
concrete_component = ConcreteComponent()
concrete_decorator_a = ConcreteDecoratorA(concrete_component)
concrete_decorator_b = ConcreteDecoratorB(concrete_decorator_a)
concrete_decorator_b.operation()


if __name__ == "__main__":
main()

桥模式

  • 使用场景:一般用于两个非常强的变化维度上

就是具体抽象化角色调用具体实现化角色

  • 抽象化角色
  • 具体抽象化角色
  • 实现化角色
  • 具体实现化角色
1
2
3
implementation = 具体实现化角色()
abstraction = 具体抽象化角色(implementation)
abstraction.operation()

对象创建

工厂方法

  • 使用场景:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

  1. 创建抽象工厂类,定义具体工厂的公共接口;
  2. 创建抽象产品类 ,定义具体产品的公共接口;
  3. 创建具体产品类(继承抽象产品类),定义生产的具体产品;
  4. 创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法
  5. 外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例

产品,工厂都是抽象的

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
"""
Define an interface for creating an object, but let subclasses decide
which class to instantiate. Factory Method lets a class defer
instantiation to subclasses.
"""

import abc


class Creator(metaclass=abc.ABCMeta):
"""
Declare the factory method, which returns an object of type Product.
Creator may also define a default implementation of the factory
method that returns a default ConcreteProduct object.
Call the factory method to create a Product object.
"""

def __init__(self):
self.product = self._factory_method()

@abc.abstractmethod
def _factory_method(self):
pass

def some_operation(self):
self.product.interface()


class ConcreteCreator1(Creator):
"""
Override the factory method to return an instance of a
ConcreteProduct1.
"""

def _factory_method(self):
return ConcreteProduct1()


class ConcreteCreator2(Creator):
"""
Override the factory method to return an instance of a
ConcreteProduct2.
"""

def _factory_method(self):
return ConcreteProduct2()


class Product(metaclass=abc.ABCMeta):
"""
Define the interface of objects the factory method creates.
"""

@abc.abstractmethod
def interface(self):
pass


class ConcreteProduct1(Product):
"""
Implement the Product interface.
"""

def interface(self):
pass


class ConcreteProduct2(Product):
"""
Implement the Product interface.
"""

def interface(self):
pass


def main():
concrete_creator = ConcreteCreator1()
concrete_creator.product.interface()
concrete_creator.some_operation()


if __name__ == "__main__":
main()

原型模式

  • 使用场景:通过给出一个原型对象来指明所有创建的对象的类型
    • 复制比创建新对象花费少得多
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
"""
Specify the kinds of objects to create using a prototypical instance,
and create new objects by copying this prototype.
"""

import copy


class Prototype:
"""
Example class to be copied.
"""

pass


def main():
prototype = Prototype()
prototype_copy = copy.deepcopy(prototype)


if __name__ == "__main__":
main()

构建器

  • 使用场景:比如爬虫,可能要加载储存的cookies,初始化user-agent,登录,一系列创建的操作
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
158
159
160
161
from __future__ import annotations
from abc import ABC, abstractmethod, abstractproperty
from typing import Any


class Builder(ABC):
"""
The Builder interface specifies methods for creating the different parts of
the Product objects.
"""

@abstractproperty
def product(self) -> None:
pass

@abstractmethod
def produce_part_a(self) -> None:
pass

@abstractmethod
def produce_part_b(self) -> None:
pass

@abstractmethod
def produce_part_c(self) -> None:
pass


class ConcreteBuilder1(Builder):
"""
The Concrete Builder classes follow the Builder interface and provide
specific implementations of the building steps. Your program may have
several variations of Builders, implemented differently.
"""

def __init__(self) -> None:
"""
A fresh builder instance should contain a blank product object, which is
used in further assembly.
"""
self.reset()

def reset(self) -> None:
self._product = Product1()

@property
def product(self) -> Product1:
"""
Concrete Builders are supposed to provide their own methods for
retrieving results. That's because various types of builders may create
entirely different products that don't follow the same interface.
Therefore, such methods cannot be declared in the base Builder interface
(at least in a statically typed programming language).

Usually, after returning the end result to the client, a builder
instance is expected to be ready to start producing another product.
That's why it's a usual practice to call the reset method at the end of
the `getProduct` method body. However, this behavior is not mandatory,
and you can make your builders wait for an explicit reset call from the
client code before disposing of the previous result.
"""
product = self._product
self.reset()
return product

def produce_part_a(self) -> None:
self._product.add("PartA1")

def produce_part_b(self) -> None:
self._product.add("PartB1")

def produce_part_c(self) -> None:
self._product.add("PartC1")


class Product1():
"""
It makes sense to use the Builder pattern only when your products are quite
complex and require extensive configuration.

Unlike in other creational patterns, different concrete builders can produce
unrelated products. In other words, results of various builders may not
always follow the same interface.
"""

def __init__(self) -> None:
self.parts = []

def add(self, part: Any) -> None:
self.parts.append(part)

def list_parts(self) -> None:
print(f"Product parts: {', '.join(self.parts)}", end="")


class Director:
"""
The Director is only responsible for executing the building steps in a
particular sequence. It is helpful when producing products according to a
specific order or configuration. Strictly speaking, the Director class is
optional, since the client can control builders directly.
"""

def __init__(self) -> None:
self._builder = None

@property
def builder(self) -> Builder:
return self._builder

@builder.setter
def builder(self, builder: Builder) -> None:
"""
The Director works with any builder instance that the client code passes
to it. This way, the client code may alter the final type of the newly
assembled product.
"""
self._builder = builder

"""
The Director can construct several product variations using the same
building steps.
"""

def build_minimal_viable_product(self) -> None:
self.builder.produce_part_a()

def build_full_featured_product(self) -> None:
self.builder.produce_part_a()
self.builder.produce_part_b()
self.builder.produce_part_c()


if __name__ == "__main__":
"""
The client code creates a builder object, passes it to the director and then
initiates the construction process. The end result is retrieved from the
builder object.
"""

director = Director()
builder = ConcreteBuilder1()
director.builder = builder

print("Standard basic product: ")
director.build_minimal_viable_product()
builder.product.list_parts()

print("\n")

print("Standard full featured product: ")
director.build_full_featured_product()
builder.product.list_parts()

print("\n")

# Remember, the Builder pattern can be used without a Director class.
print("Custom product: ")
builder.produce_part_a()
builder.produce_part_b()
builder.product.list_parts()

单件模式

  • 使用场景:全局只需要一个实例,如:配置文件,数据库连接句柄
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
"""
Ensure a class only has one instance, and provide a global point of
access to it.
"""


class Singleton(type):
"""
Define an Instance operation that lets clients access its unique
instance.
"""

def __init__(cls, name, bases, attrs, **kwargs):
super().__init__(name, bases, attrs)
cls._instance = None

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


class MyClass(metaclass=Singleton):
"""
Example class.
"""

pass


def main():
m1 = MyClass()
m2 = MyClass()
assert m1 is m2


if __name__ == "__main__":
main()

享元模式

  • 使用场景:需要大量相同实例,实例一部分属性相同,一部分不同。常见于游戏中的实例
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
"""
Use sharing to support large numbers of fine-grained objects
efficiently.
"""

import abc


class FlyweightFactory:
"""
Create and manage flyweight objects.
Ensure that flyweights are shared properly. When a client requests a
flyweight, the FlyweightFactory object supplies an existing instance
or creates one, if none exists.
"""

def __init__(self):
self._flyweights = {}

def get_flyweight(self, key):
try:
flyweight = self._flyweights[key]
except KeyError:
flyweight = ConcreteFlyweight()
self._flyweights[key] = flyweight
return flyweight


class Flyweight(metaclass=abc.ABCMeta):
"""
Declare an interface through which flyweights can receive and act on
extrinsic state.
"""

def __init__(self):
self.intrinsic_state = None

@abc.abstractmethod
def operation(self, extrinsic_state):
pass


class ConcreteFlyweight(Flyweight):
"""
Implement the Flyweight interface and add storage for intrinsic
state, if any. A ConcreteFlyweight object must be sharable. Any
state it stores must be intrinsic; that is, it must be independent
of the ConcreteFlyweight object's context.
"""

def operation(self, extrinsic_state):
pass


def main():
flyweight_factory = FlyweightFactory()
concrete_flyweight = flyweight_factory.get_flyweight("key")
concrete_flyweight.operation(None)


if __name__ == "__main__":
main()

接口隔离

外观模式

  • 使用场景:一个操作需要大量流程,但是这些流程对外是不需要的
    • 比如:下载视频,可能需要登录,访问,保存,但是只需要给一个接口
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
"""
Provide a unified interface to a set of interfaces in a subsystem.
Facade defines a higher-level interface that makes the subsystem easier
to use.
"""


class Facade:
"""
Know which subsystem classes are responsible for a request.
Delegate client requests to appropriate subsystem objects.
"""

def __init__(self):
self._subsystem_1 = Subsystem1()
self._subsystem_2 = Subsystem2()

def operation(self):
self._subsystem_1.operation1()
self._subsystem_1.operation2()
self._subsystem_2.operation1()
self._subsystem_2.operation2()


class Subsystem1:
"""
Implement subsystem functionality.
Handle work assigned by the Facade object.
Have no knowledge of the facade; that is, they keep no references to
it.
"""

def operation1(self):
pass

def operation2(self):
pass


class Subsystem2:
"""
Implement subsystem functionality.
Handle work assigned by the Facade object.
Have no knowledge of the facade; that is, they keep no references to
it.
"""

def operation1(self):
pass

def operation2(self):
pass


def main():
facade = Facade()
facade.operation()


if __name__ == "__main__":
main()

代理模式

  • 使用场景:为其他对象提供一种代理以控制这个对象的访问或调用
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
from abc import ABC, abstractmethod


class Subject(ABC):
"""
The Subject interface declares common operations for both RealSubject and
the Proxy. As long as the client works with RealSubject using this
interface, you'll be able to pass it a proxy instead of a real subject.
"""

@abstractmethod
def request(self) -> None:
pass


class RealSubject(Subject):
"""
The RealSubject contains some core business logic. Usually, RealSubjects are
capable of doing some useful work which may also be very slow or sensitive -
e.g. correcting input data. A Proxy can solve these issues without any
changes to the RealSubject's code.
"""

def request(self) -> None:
print("RealSubject: Handling request.")


class Proxy(Subject):
"""
The Proxy has an interface identical to the RealSubject.
"""

def __init__(self, real_subject: RealSubject) -> None:
self._real_subject = real_subject

def request(self) -> None:
"""
The most common applications of the Proxy pattern are lazy loading,
caching, controlling the access, logging, etc. A Proxy can perform one
of these things and then, depending on the result, pass the execution to
the same method in a linked RealSubject object.
"""

if self.check_access():
self._real_subject.request()
self.log_access()

def check_access(self) -> bool:
print("Proxy: Checking access prior to firing a real request.")
return True

def log_access(self) -> None:
print("Proxy: Logging the time of request.", end="")


def client_code(subject: Subject) -> None:
"""
The client code is supposed to work with all objects (both subjects and
proxies) via the Subject interface in order to support both real subjects
and proxies. In real life, however, clients mostly work with their real
subjects directly. In this case, to implement the pattern more easily, you
can extend your proxy from the real subject's class.
"""

# ...

subject.request()

# ...


if __name__ == "__main__":
print("Client: Executing the client code with a real subject:")
real_subject = RealSubject()
client_code(real_subject)

print("")

print("Client: Executing the same client code with a proxy:")
proxy = Proxy(real_subject)
client_code(proxy)

适配器模式

  • 使用场景:比如JsonToStruct
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
"""
Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
"""

import abc


class Target(metaclass=abc.ABCMeta):
"""
Define the domain-specific interface that Client uses.
"""

def __init__(self):
self._adaptee = Adaptee()

@abc.abstractmethod
def request(self):
pass


class Adapter(Target):
"""
Adapt the interface of Adaptee to the Target interface.
"""

def request(self):
self._adaptee.specific_request()


class Adaptee:
"""
Define an existing interface that needs adapting.
"""

def specific_request(self):
pass


def main():
adapter = Adapter()
adapter.request()


if __name__ == "__main__":
main()

中介者模式

  • 使用场景:多个对象互相依赖交互,
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
"""
Define an object that encapsulates how a set of objects interact.
Mediator promotes loose coupling by keeping objects from referring to
each other explicitly, and it lets you vary their interaction
independently.
"""


class Mediator:
"""
Implement cooperative behavior by coordinating Colleague objects.
Know and maintains its colleagues.
"""

def __init__(self):
self._colleague_1 = Colleague1(self)
self._colleague_2 = Colleague2(self)


class Colleague1:
"""
Know its Mediator object.
Communicate with its mediator whenever it would have otherwise
communicated with another colleague.
"""

def __init__(self, mediator):
self._mediator = mediator


class Colleague2:
"""
Know its Mediator object.
Communicate with its mediator whenever it would have otherwise
communicated with another colleague.
"""

def __init__(self, mediator):
self._mediator = mediator


def main():
mediator = Mediator()


if __name__ == "__main__":
main()

状态变化

状态模式

  • 使用场景:有不同状态,每个状态需要不同的操作
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
"""
Allow an object to alter its behavior when its internal state changes.
The object will appear to change its class.
"""

import abc


class Context:
"""
Define the interface of interest to clients.
Maintain an instance of a ConcreteState subclass that defines the
current state.
"""

def __init__(self, state):
self._state = state

def request(self):
self._state.handle()


class State(metaclass=abc.ABCMeta):
"""
Define an interface for encapsulating the behavior associated with a
particular state of the Context.
"""

@abc.abstractmethod
def handle(self):
pass


class ConcreteStateA(State):
"""
Implement a behavior associated with a state of the Context.
"""

def handle(self):
pass


class ConcreteStateB(State):
"""
Implement a behavior associated with a state of the Context.
"""

def handle(self):
pass


def main():
concrete_state_a = ConcreteStateA()
context = Context(concrete_state_a)
context.request()


if __name__ == "__main__":
main()

备忘录模式

  • 使用场景:有不同状态,需要返回到某个状态,类似git,undo
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
"""
Capture and externalize an object's internal state so that the object
can be restored to this state later, without violating encapsulation.
"""

import pickle


class Originator:
"""
Create a memento containing a snapshot of its current internal
state.
Use the memento to restore its internal state.
"""

def __init__(self):
self._state = None

def set_memento(self, memento):
previous_state = pickle.loads(memento)
vars(self).clear()
vars(self).update(previous_state)

def create_memento(self):
return pickle.dumps(vars(self))


def main():
originator = Originator()
memento = originator.create_memento()
originator._state = True
originator.set_memento(memento)


if __name__ == "__main__":
main()

数据结构

组合模式

  • 使用场景:它可以让叶子对象和容器对象的使用具有一致性
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
"""
Compose objects into tree structures to represent part-whole
hierarchies. Composite lets clients treat individual objects and
compositions of objects uniformly.
"""

import abc


class Component(metaclass=abc.ABCMeta):
"""
Declare the interface for objects in the composition.
Implement default behavior for the interface common to all classes,
as appropriate.
Declare an interface for accessing and managing its child
components.
Define an interface for accessing a component's parent in the
recursive structure, and implement it if that's appropriate
(optional).
"""

@abc.abstractmethod
def operation(self):
pass


class Composite(Component):
"""
Define behavior for components having children.
Store child components.
Implement child-related operations in the Component interface.
"""

def __init__(self):
self._children = set()

def operation(self):
for child in self._children:
child.operation()

def add(self, component):
self._children.add(component)

def remove(self, component):
self._children.discard(component)


class Leaf(Component):
"""
Represent leaf objects in the composition. A leaf has no children.
Define behavior for primitive objects in the composition.
"""

def operation(self):
pass


def main():
leaf = Leaf()
composite = Composite()
composite.add(leaf)
composite.operation()


if __name__ == "__main__":
main()

责任链模式

  • 使用场景:当程序需要使用不同方式处理不同种类请求
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
"""
Avoid coupling the sender of a request to its receiver by giving
more than one object a chance to handle the request. Chain the receiving
objects and pass the request along the chain until an object handles it.
"""

import abc


class Handler(metaclass=abc.ABCMeta):
"""
Define an interface for handling requests.
Implement the successor link.
"""

def __init__(self, successor=None):
self._successor = successor

@abc.abstractmethod
def handle_request(self):
pass


class ConcreteHandler1(Handler):
"""
Handle request, otherwise forward it to the successor.
"""

def handle_request(self):
if True: # if can_handle:
pass
elif self._successor is not None:
self._successor.handle_request()


class ConcreteHandler2(Handler):
"""
Handle request, otherwise forward it to the successor.
"""

def handle_request(self):
if False: # if can_handle:
pass
elif self._successor is not None:
self._successor.handle_request()


def main():
concrete_handler_1 = ConcreteHandler1()
concrete_handler_2 = ConcreteHandler2(concrete_handler_1)
concrete_handler_2.handle_request()


if __name__ == "__main__":
main()

参考