本文源碼寄方於github:https://github.com/w392807287/Design_pattern_of_pythonnode
參考文獻:python
《大話設計模式》——吳強git
《Python設計模式》——pythontip.comgithub
《23種設計模式》——http://www.cnblogs.com/beijiguangyong/正則表達式
設計模式是通過總結、優化的,對咱們常常會碰到的一些編程問題的可重用解決方案。一個設計模式並不像一個類或一個庫那樣可以直接做用於咱們的代碼。反之,設計模式更爲高級,它是一種必須在特定情形下實現的一種方法模板。設計模式不會綁定具體的編程語言。一個好的設計模式應該可以用大部分編程語言實現(若是作不到所有的話,具體取決於語言特性)。最爲重要的是,設計模式也是一把雙刃劍,若是設計模式被用在不恰當的情形下將會形成災難,進而帶來無窮的麻煩。然而若是設計模式在正確的時間被用在正確地地方,它將是你的救星。算法
起初,你會認爲「模式」就是爲了解決一類特定問題而特別想出來的明智之舉。說的沒錯,看起來的確是經過不少人一塊兒工做,從不一樣的角度看待問題進而造成的一個最通用、最靈活的解決方案。也許這些問題你曾經見過或是曾經解決過,可是你的解決方案極可能沒有模式這麼完備。編程
雖然被稱爲「設計模式」,可是它們同「設計「領域並不是緊密聯繫。設計模式同傳統意義上的分析、設計與實現不一樣,事實上設計模式將一個完整的理念根植於程序中,因此它可能出如今分析階段或是更高層的設計階段。頗有趣的是由於設計模式的具體體現是程序代碼,所以可能會讓你認爲它不會在具體實現階段以前出現(事實上在進入具體實現階段以前你都沒有意識到正在使用具體的設計模式)。設計模式
能夠經過程序設計的基本概念來理解模式:增長一個抽象層。抽象一個事物就是隔離任何具體細節,這麼作的目的是爲了將那些不變的核心部分從其餘細節中分離出來。當你發現你程序中的某些部分常常由於某些緣由改動,而你不想讓這些改動的部分引起其餘部分的改動,這時候你就須要思考那些不會變更的設計方法了。這麼作不只會使代碼可維護性更高,並且會讓代碼更易於理解,從而下降開發成本。api
這裏列舉了三種最基本的設計模式:數據結構
建立型
1. Factory Method(工廠方法)
2. Abstract Factory(抽象工廠)
3. Builder(建造者)
4. Prototype(原型)
5. Singleton(單例)
結構型
6. Adapter Class/Object(適配器)
7. Bridge(橋接)
8. Composite(組合)
9. Decorator(裝飾)
10. Facade(外觀)
11. Flyweight(享元)
12. Proxy(代理)
行爲型
13. Interpreter(解釋器)
14. Template Method(模板方法)
15. Chain of Responsibility(責任鏈)
16. Command(命令)
17. Iterator(迭代器)
18. Mediator(中介者)
19. Memento(備忘錄)
20. Observer(觀察者)
21. State(狀態)
22. Strategy(策略)
23. Visitor(訪問者)
意圖:
定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method 使一個類的實例化延遲到其子類。
適用性:
當一個類不知道它所必須建立的對象的類的時候。
當一個類但願由它的子類來指定它所建立的對象的時候。
當類將建立對象的職責委託給多個幫助子類中的某一個,而且你但願將哪個幫助子類是代理者這一信息局部化的時候。
實現:
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
|
#!/usr/bin/python
#coding:utf8
'''
Factory Method
'''
class
ChinaGetter:
"""A simple localizer a la gettext"""
def
__init__(
self
):
self
.trans
=
dict
(dog
=
u
"小狗"
, cat
=
u
"小貓"
)
def
get(
self
, msgid):
"""We'll punt if we don't have a translation"""
try
:
return
self
.trans[msgid]
except
KeyError:
return
str
(msgid)
class
EnglishGetter:
"""Simply echoes the msg ids"""
def
get(
self
, msgid):
return
str
(msgid)
def
get_localizer(language
=
"English"
):
"""The factory method"""
languages
=
dict
(English
=
EnglishGetter, China
=
ChinaGetter)
return
languages[language]()
# Create our localizers
e, g
=
get_localizer(
"English"
), get_localizer(
"China"
)
# Localize some text
for
msgid
in
"dog parrot cat bear"
.split():
print
(e.get(msgid), g.get(msgid))
|
意圖:
提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
適用性:
一個系統要獨立於它的產品的建立、組合和表示時。
一個系統要由多個產品系列中的一個來配置時。
當你要強調一系列相關的產品對象的設計以便進行聯合使用時。
當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。
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
|
#!/usr/bin/python
#coding:utf8
'''
Abstract Factory
'''
import
random
class
PetShop:
"""A pet shop"""
def
__init__(
self
, animal_factory
=
None
):
"""pet_factory is our abstract factory.
We can set it at will."""
self
.pet_factory
=
animal_factory
def
show_pet(
self
):
"""Creates and shows a pet using the
abstract factory"""
pet
=
self
.pet_factory.get_pet()
print
(
"This is a lovely"
,
str
(pet))
print
(
"It says"
, pet.speak())
print
(
"It eats"
,
self
.pet_factory.get_food())
# Stuff that our factory makes
class
Dog:
def
speak(
self
):
return
"woof"
def
__str__(
self
):
return
"Dog"
class
Cat:
def
speak(
self
):
return
"meow"
def
__str__(
self
):
return
"Cat"
# Factory classes
class
DogFactory:
def
get_pet(
self
):
return
Dog()
def
get_food(
self
):
return
"dog food"
class
CatFactory:
def
get_pet(
self
):
return
Cat()
def
get_food(
self
):
return
"cat food"
# Create the proper family
def
get_factory():
"""Let's be dynamic!"""
return
random.choice([DogFactory, CatFactory])()
# Show pets with various factories
if
__name__
=
=
"__main__"
:
shop
=
PetShop()
for
i
in
range
(
3
):
shop.pet_factory
=
get_factory()
shop.show_pet()
print
(
"="
*
20
)
|
意圖:
將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。
適用性:
當建立複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。
當構造過程必須容許被構造的對象有不一樣的表示時。
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
|
#!/usr/bin/python
#coding:utf8
"""
Builder
"""
# Director
class
Director(
object
):
def
__init__(
self
):
self
.builder
=
None
def
construct_building(
self
):
self
.builder.new_building()
self
.builder.build_floor()
self
.builder.build_size()
def
get_building(
self
):
return
self
.builder.building
# Abstract Builder
class
Builder(
object
):
def
__init__(
self
):
self
.building
=
None
def
new_building(
self
):
self
.building
=
Building()
# Concrete Builder
class
BuilderHouse(Builder):
def
build_floor(
self
):
self
.building.floor
=
'One'
def
build_size(
self
):
self
.building.size
=
'Big'
class
BuilderFlat(Builder):
def
build_floor(
self
):
self
.building.floor
=
'More than One'
def
build_size(
self
):
self
.building.size
=
'Small'
# Product
class
Building(
object
):
def
__init__(
self
):
self
.floor
=
None
self
.size
=
None
def
__repr__(
self
):
return
'Floor: %s | Size: %s'
%
(
self
.floor,
self
.size)
# Client
if
__name__
=
=
"__main__"
:
director
=
Director()
director.builder
=
BuilderHouse()
director.construct_building()
building
=
director.get_building()
print
(building)
director.builder
=
BuilderFlat()
director.construct_building()
building
=
director.get_building()
print
(building)
|
意圖:
用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。
適用性:
當要實例化的類是在運行時刻指定時,例如,經過動態裝載;或者爲了不建立一個與產品類層次平行的工廠類層次時;或者當一個類的實例只能有幾個不一樣狀態組合中的一種時。創建相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。
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
|
#!/usr/bin/python
#coding:utf8
'''
Prototype
'''
import
copy
class
Prototype:
def
__init__(
self
):
self
._objects
=
{}
def
register_object(
self
, name, obj):
"""Register an object"""
self
._objects[name]
=
obj
def
unregister_object(
self
, name):
"""Unregister an object"""
del
self
._objects[name]
def
clone(
self
, name,
*
*
attr):
"""Clone a registered object and update inner attributes dictionary"""
obj
=
copy.deepcopy(
self
._objects.get(name))
obj.__dict__.update(attr)
return
obj
def
main():
class
A:
def
__str__(
self
):
return
"I am A"
a
=
A()
prototype
=
Prototype()
prototype.register_object(
'a'
, a)
b
=
prototype.clone(
'a'
, a
=
1
, b
=
2
, c
=
3
)
print
(a)
print
(b.a, b.b, b.c)
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
|
#!/usr/bin/python
#coding:utf8
'''
Singleton
'''
class
Singleton(
object
):
''''' A python style singleton '''
def
__new__(
cls
,
*
args,
*
*
kw):
if
not
hasattr
(
cls
,
'_instance'
):
org
=
super
(Singleton,
cls
)
cls
._instance
=
org.__new__(
cls
,
*
args,
*
*
kw)
return
cls
._instance
if
__name__
=
=
'__main__'
:
class
SingleSpam(Singleton):
def
__init__(
self
, s):
self
.s
=
s
def
__str__(
self
):
return
self
.s
s1
=
SingleSpam(
'spam'
)
print
id
(s1), s1
s2
=
SingleSpam(
'spa'
)
print
id
(s2), s2
print
id
(s1), s1
|
意圖:
將一個類的接口轉換成客戶但願的另一個接口。Adapter 模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。
適用性:
你想使用一個已經存在的類,而它的接口不符合你的需求。
你想建立一個能夠複用的類,該類能夠與其餘不相關的類或不可預見的類(即那些接口可能不必定兼容的類)協同工做。
(僅適用於對象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
73
74
75
76
|
#!/usr/bin/python
#coding:utf8
'''
Adapter
'''
import
os
class
Dog(
object
):
def
__init__(
self
):
self
.name
=
"Dog"
def
bark(
self
):
return
"woof!"
class
Cat(
object
):
def
__init__(
self
):
self
.name
=
"Cat"
def
meow(
self
):
return
"meow!"
class
Human(
object
):
def
__init__(
self
):
self
.name
=
"Human"
def
speak(
self
):
return
"'hello'"
class
Car(
object
):
def
__init__(
self
):
self
.name
=
"Car"
def
make_noise(
self
, octane_level):
return
"vroom%s"
%
(
"!"
*
octane_level)
class
Adapter(
object
):
"""
Adapts an object by replacing methods.
Usage:
dog = Dog
dog = Adapter(dog, dict(make_noise=dog.bark))
"""
def
__init__(
self
, obj, adapted_methods):
"""We set the adapted methods in the object's dict"""
self
.obj
=
obj
self
.__dict__.update(adapted_methods)
def
__getattr__(
self
, attr):
"""All non-adapted calls are passed to the object"""
return
getattr
(
self
.obj, attr)
def
main():
objects
=
[]
dog
=
Dog()
objects.append(Adapter(dog,
dict
(make_noise
=
dog.bark)))
cat
=
Cat()
objects.append(Adapter(cat,
dict
(make_noise
=
cat.meow)))
human
=
Human()
objects.append(Adapter(human,
dict
(make_noise
=
human.speak)))
car
=
Car()
car_noise
=
lambda
: car.make_noise(
3
)
objects.append(Adapter(car,
dict
(make_noise
=
car_noise)))
for
obj
in
objects:
print
"A"
, obj.name,
"goes"
, obj.make_noise()
if
__name__
=
=
"__main__"
:
main()
|
意圖:
將抽象部分與它的實現部分分離,使它們均可以獨立地變化。
適用性:
你不但願在抽象和它的實現部分之間有一個固定的綁定關係。例如這種狀況多是由於,在程序運行時刻實現部分應能夠被選擇或者切換。
類的抽象以及它的實現都應該能夠經過生成子類的方法加以擴充。這時Bridge 模式使你能夠對不一樣的抽象接口和實現部分進行組合,並分別對它們進行擴充。
對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼沒必要從新編譯。
(C++)你想對客戶徹底隱藏抽象的實現部分。在C++中,類的表示在類接口中是可見的。
有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh 稱這種類層次結構爲「嵌套的普化」(nested generalizations )。
你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子即是Coplien 的String 類[ Cop92 ],在這個類中多個對象能夠共享同一個字符串表示(StringRep)。
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
|
#!/usr/bin/python
#coding:utf8
'''
Bridge
'''
# ConcreteImplementor 1/2
class
DrawingAPI1(
object
):
def
draw_circle(
self
, x, y, radius):
print
(
'API1.circle at {}:{} radius {}'
.
format
(x, y, radius))
# ConcreteImplementor 2/2
class
DrawingAPI2(
object
):
def
draw_circle(
self
, x, y, radius):
print
(
'API2.circle at {}:{} radius {}'
.
format
(x, y, radius))
# Refined Abstraction
class
CircleShape(
object
):
def
__init__(
self
, x, y, radius, drawing_api):
self
._x
=
x
self
._y
=
y
self
._radius
=
radius
self
._drawing_api
=
drawing_api
# low-level i.e. Implementation specific
def
draw(
self
):
self
._drawing_api.draw_circle(
self
._x,
self
._y,
self
._radius)
# high-level i.e. Abstraction specific
def
scale(
self
, pct):
self
._radius
*
=
pct
def
main():
shapes
=
(
CircleShape(
1
,
2
,
3
, DrawingAPI1()),
CircleShape(
5
,
7
,
11
, DrawingAPI2())
)
for
shape
in
shapes:
shape.scale(
2.5
)
shape.draw()
if
__name__
=
=
'__main__'
:
main()
|
意圖:
將對象組合成樹形結構以表示「部分-總體」的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具備一致性。
適用性:
你想表示對象的部分-總體層次結構。
你但願用戶忽略組合對象與單個對象的不一樣,用戶將統一地使用組合結構中的全部對象。
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
|
#!/usr/bin/python
#coding:utf8
"""
Composite
"""
class
Component:
def
__init__(
self
,strName):
self
.m_strName
=
strName
def
Add(
self
,com):
pass
def
Display(
self
,nDepth):
pass
class
Leaf(Component):
def
Add(
self
,com):
print
"leaf can't add"
def
Display(
self
,nDepth):
strtemp
=
"-"
*
nDepth
strtemp
=
strtemp
+
self
.m_strName
print
strtemp
class
Composite(Component):
def
__init__(
self
,strName):
self
.m_strName
=
strName
self
.c
=
[]
def
Add(
self
,com):
self
.c.append(com)
def
Display(
self
,nDepth):
strtemp
=
"-"
*
nDepth
strtemp
=
strtemp
+
self
.m_strName
print
strtemp
for
com
in
self
.c:
com.Display(nDepth
+
2
)
if
__name__
=
=
"__main__"
:
p
=
Composite(
"Wong"
)
p.Add(Leaf(
"Lee"
))
p.Add(Leaf(
"Zhao"
))
p1
=
Composite(
"Wu"
)
p1.Add(Leaf(
"San"
))
p.Add(p1)
p.Display(
1
);
|
意圖:
動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator 模式相比生成子類更爲靈活。
適用性:
在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。
處理那些能夠撤消的職責。
當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。
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
|
#!/usr/bin/python
#coding:utf8
'''
Decorator
'''
class
foo(
object
):
def
f1(
self
):
print
(
"original f1"
)
def
f2(
self
):
print
(
"original f2"
)
class
foo_decorator(
object
):
def
__init__(
self
, decoratee):
self
._decoratee
=
decoratee
def
f1(
self
):
print
(
"decorated f1"
)
self
._decoratee.f1()
def
__getattr__(
self
, name):
return
getattr
(
self
._decoratee, name)
u
=
foo()
v
=
foo_decorator(u)
v.f1()
v.f2()
|
意圖:
爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。
適用性:
當你要爲一個複雜子系統提供一個簡單接口時。子系統每每由於不斷演化而變得愈來愈複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不須要定製子系統的用戶帶來一些使用上的困難。Facade 能夠提供一個簡單的缺省視圖,這一視圖對大多數用戶來講已經足夠,而那些須要更多的可定製性的用戶能夠越過facade層。
客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入facade 將這個子系統與客戶以及其餘的子系統分離,能夠提升子系統的獨立性和可移植性。
當你須要構建一個層次結構的子系統時,使用facade模式定義子系統中每層的入口點。若是子系統之間是相互依賴的,你可讓它們僅經過facade進行通信,從而簡化了它們之間的依賴關係。
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
|
#!/usr/bin/python
#coding:utf8
'''
Decorator
'''
import
time
SLEEP
=
0.5
# Complex Parts
class
TC1:
def
run(
self
):
print
(
"###### In Test 1 ######"
)
time.sleep(SLEEP)
print
(
"Setting up"
)
time.sleep(SLEEP)
print
(
"Running test"
)
time.sleep(SLEEP)
print
(
"Tearing down"
)
time.sleep(SLEEP)
print
(
"Test Finished\n"
)
class
TC2:
def
run(
self
):
print
(
"###### In Test 2 ######"
)
time.sleep(SLEEP)
print
(
"Setting up"
)
time.sleep(SLEEP)
print
(
"Running test"
)
time.sleep(SLEEP)
print
(
"Tearing down"
)
time.sleep(SLEEP)
print
(
"Test Finished\n"
)
class
TC3:
def
run(
self
):
print
(
"###### In Test 3 ######"
)
time.sleep(SLEEP)
print
(
"Setting up"
)
time.sleep(SLEEP)
print
(
"Running test"
)
time.sleep(SLEEP)
print
(
"Tearing down"
)
time.sleep(SLEEP)
print
(
"Test Finished\n"
)
# Facade
class
TestRunner:
def
__init__(
self
):
self
.tc1
=
TC1()
self
.tc2
=
TC2()
self
.tc3
=
TC3()
self
.tests
=
[i
for
i
in
(
self
.tc1,
self
.tc2,
self
.tc3)]
def
runAll(
self
):
[i.run()
for
i
in
self
.tests]
# Client
if
__name__
=
=
'__main__'
:
testrunner
=
TestRunner()
testrunner.runAll()
|
意圖:
運用共享技術有效地支持大量細粒度的對象。
適用性:
一個應用程序使用了大量的對象。
徹底因爲使用大量的對象,形成很大的存儲開銷。
對象的大多數狀態均可變爲外部狀態。
若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象。
應用程序不依賴於對象標識。因爲Flyweight 對象能夠被共享,對於概念上明顯有別的對象,標識測試將返回真值。
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
|
#!/usr/bin/python
#coding:utf8
'''
Flyweight
'''
import
weakref
class
Card(
object
):
"""The object pool. Has builtin reference counting"""
_CardPool
=
weakref.WeakValueDictionary()
"""Flyweight implementation. If the object exists in the
pool just return it (instead of creating a new one)"""
def
__new__(
cls
, value, suit):
obj
=
Card._CardPool.get(value
+
suit,
None
)
if
not
obj:
obj
=
object
.__new__(
cls
)
Card._CardPool[value
+
suit]
=
obj
obj.value, obj.suit
=
value, suit
return
obj
# def __init__(self, value, suit):
# self.value, self.suit = value, suit
def
__repr__(
self
):
return
"<Card: %s%s>"
%
(
self
.value,
self
.suit)
if
__name__
=
=
'__main__'
:
# comment __new__ and uncomment __init__ to see the difference
c1
=
Card(
'9'
,
'h'
)
c2
=
Card(
'9'
,
'h'
)
print
(c1, c2)
print
(c1
=
=
c2)
print
(
id
(c1),
id
(c2))
|
意圖:
爲其餘對象提供一種代理以控制對這個對象的訪問。
適用性:
在須要用比較通用和複雜的對象指針代替簡單的指針的時候,使用Proxy模式。下面是一 些可使用Proxy 模式常見狀況:
1) 遠程代理(Remote Proxy )爲一個對象在不一樣的地址空間提供局部表明。 NEXTSTEP[Add94] 使用NXProxy 類實現了這一目的。Coplien[Cop92] 稱這種代理爲「大使」 (Ambassador )。
2 )虛代理(Virtual Proxy )根據須要建立開銷很大的對象。在動機一節描述的ImageProxy 就是這樣一種代理的例子。
3) 保護代理(Protection Proxy )控制對原始對象的訪問。保護代理用於對象應該有不一樣 的訪問權限的時候。例如,在Choices 操做系統[ CIRM93]中KemelProxies爲操做系統對象提供 了訪問保護。
4 )智能指引(Smart Reference )取代了簡單的指針,它在訪問對象時執行一些附加操做。 它的典型用途包括:對指向實際對象的引用計數,這樣當該對象沒有引用時,能夠自動釋放它(也稱爲SmartPointers[Ede92 ] )。
當第一次引用一個持久對象時,將它裝入內存。
在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其餘對象不能改變它。
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
|
#!/usr/bin/python
#coding:utf8
'''
Proxy
'''
import
time
class
SalesManager:
def
work(
self
):
print
(
"Sales Manager working..."
)
def
talk(
self
):
print
(
"Sales Manager ready to talk"
)
class
Proxy:
def
__init__(
self
):
self
.busy
=
'No'
self
.sales
=
None
def
work(
self
):
print
(
"Proxy checking for Sales Manager availability"
)
if
self
.busy
=
=
'No'
:
self
.sales
=
SalesManager()
time.sleep(
2
)
self
.sales.talk()
else
:
time.sleep(
2
)
print
(
"Sales Manager is busy"
)
if
__name__
=
=
'__main__'
:
p
=
Proxy()
p.work()
p.busy
=
'Yes'
p.work()
|
意圖:
給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
適用性:
當有一個語言須要解釋執行, 而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。而當存在如下狀況時該模式效果最好:
該文法簡單對於複雜的文法, 文法的類層次變得龐大而沒法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹便可解釋表達式, 這樣能夠節省空間並且還可能節省時間。
效率不是一個關鍵問題最高效的解釋器一般不是經過直接解釋語法分析樹實現的, 而是首先將它們轉換成另外一種形式。例如,正則表達式一般被轉換成狀態機。但即便在這種狀況下, 轉換器仍可用解釋器模式實現, 該模式還是有用的。
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
|
#!/usr/bin/python
#coding:utf8
'''
Interpreter
'''
class
Context:
def
__init__(
self
):
self
.
input
=
""
self
.output
=
""
class
AbstractExpression:
def
Interpret(
self
,context):
pass
class
Expression(AbstractExpression):
def
Interpret(
self
,context):
print
"terminal interpret"
class
NonterminalExpression(AbstractExpression):
def
Interpret(
self
,context):
print
"Nonterminal interpret"
if
__name__
=
=
"__main__"
:
context
=
""
c
=
[]
c
=
c
+
[Expression()]
c
=
c
+
[NonterminalExpression()]
c
=
c
+
[Expression()]
c
=
c
+
[Expression()]
for
a
in
c:
a.Interpret(context)
|
意圖:
定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。
適用性:
一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。
各子類中公共的行爲應被提取出來並集中到一個公共父類中以免代碼重複。這是Opdyke 和Johnson所描述過的「重分解以通常化」的一個很好的例子[ OJ93 ]。首先識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。
控制子類擴展。模板方法只在特定點調用「hook 」操做(參見效果一節),這樣就只容許在這些點進行擴展。