Skip to content

Commit d29f169

Browse files
committedOct 8, 2019
no message
1 parent 249a527 commit d29f169

4 files changed

+260
-0
lines changed
 

‎结构型模式-组合模式.py

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author : ydf
3+
# @Time : 2019/10/8 0008 17:39
4+
"""
5+
组合模式
6+
组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
7+
8+
这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。
9+
10+
我们通过下面的实例来演示组合模式的用法。实例演示了一个组织中员工的层次结构。
11+
12+
介绍
13+
意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
14+
15+
主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以向处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
16+
17+
何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。
18+
19+
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
20+
21+
关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。
22+
23+
应用实例: 1、算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。 2、在 JAVA AWT 和 SWING 中,对于 Button 和 Checkbox 是树叶,Container 是树枝。
24+
25+
优点: 1、高层模块调用简单。 2、节点自由增加。
26+
27+
缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
28+
29+
使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。
30+
31+
注意事项:定义时为具体类。
32+
33+
"""
34+
from monkey_print2 import print
35+
36+
37+
# Component:公司抽象类
38+
class Company:
39+
name = ''
40+
41+
def __init__(self, name):
42+
self.name = name
43+
44+
def add(self, company):
45+
pass
46+
47+
def remove(self, company):
48+
pass
49+
50+
def display(self, depth):
51+
pass
52+
53+
def line_of_duty(self): # 履行职责
54+
pass
55+
56+
# Composite:公司类
57+
58+
59+
class ConcreteCompany(Company):
60+
childrenCompany = None
61+
62+
def __init__(self, name):
63+
Company.__init__(self, name)
64+
self.childrenCompany = []
65+
66+
def add(self, company):
67+
self.childrenCompany.append(company)
68+
69+
def remove(self, company):
70+
self.childrenCompany.remove(company)
71+
72+
def display(self, depth):
73+
print('-' * depth + self.name)
74+
75+
for component in self.childrenCompany:
76+
component.display(depth + 2)
77+
78+
def line_of_duty(self): # 履行职责
79+
for component in self.childrenCompany:
80+
component.line_of_duty()
81+
82+
83+
# Leaf:具体职能部门
84+
class HRDepartment(Company):
85+
def __init__(self, name):
86+
Company.__init__(self, name)
87+
88+
def display(self, depth):
89+
print('-' * depth + self.name)
90+
91+
def line_of_duty(self): # 履行职责
92+
print('%s\t员工招聘培训管理' % self.name)
93+
94+
95+
# Leaf:具体职能部门
96+
class FinanceDepartment(Company):
97+
def __init__(self, name):
98+
Company.__init__(self, name)
99+
100+
def display(self, depth):
101+
print('-' * depth + self.name)
102+
103+
def line_of_duty(self): # 履行职责
104+
print('%s\t公司财务收支管理' % self.name)
105+
106+
107+
108+
109+
if __name__ == '__main__':
110+
root = ConcreteCompany('北京总公司')
111+
root.add(HRDepartment('总公司人力资源部'))
112+
root.add(FinanceDepartment('总公司财务部'))
113+
114+
comp = ConcreteCompany('华东分公司')
115+
comp.add(HRDepartment('华东分公司人力资源部'))
116+
comp.add(FinanceDepartment('华东分公司财务部'))
117+
root.add(comp)
118+
119+
comp1 = ConcreteCompany('南京办事处')
120+
comp1.add(HRDepartment('南京办事处人力资源部'))
121+
comp1.add(FinanceDepartment('南京办事处财务部'))
122+
comp.add(comp1)
123+
124+
comp2 = ConcreteCompany('杭州办事处')
125+
comp2.add(HRDepartment('杭州办事处人力资源部'))
126+
comp2.add(FinanceDepartment('杭州办事处财务部'))
127+
comp.add(comp2)
128+
129+
print('-------公司结构图-------')
130+
root.display(1)
131+
132+
print('\n-------职责-------')
133+
root.line_of_duty()
134+
135+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author : ydf
3+
# @Time : 2019/10/8 0008 18:32
4+
"""
5+
函数装饰器
6+
"""
7+
import time
8+
from functools import wraps
9+
from monkey_print2 import print
10+
11+
12+
def timethis(func):
13+
'''
14+
Decorator that reports the execution time.
15+
'''
16+
17+
@wraps(func)
18+
def wrapper(*args, **kwargs):
19+
start = time.time()
20+
result = func(*args, **kwargs)
21+
end = time.time()
22+
print(func.__name__, end - start)
23+
return result
24+
25+
return wrapper
26+
27+
28+
@timethis
29+
def fun():
30+
time.sleep(3)
31+
return 1
32+
33+
34+
if __name__ == '__main__':
35+
fun()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author : ydf
3+
# @Time : 2019/10/8 0008 18:32
4+
"""
5+
类装饰器
6+
"""
7+
import types
8+
from functools import wraps
9+
from monkey_print2 import print
10+
11+
12+
13+
class Profiled:
14+
def __init__(self, func):
15+
wraps(func)(self)
16+
self.ncalls = 0
17+
18+
def __call__(self, *args, **kwargs):
19+
self.ncalls += 1
20+
return self.__wrapped__(*args, **kwargs)
21+
22+
def __get__(self, instance, cls):
23+
if instance is None:
24+
return self
25+
else:
26+
return types.MethodType(self, instance)
27+
28+
@Profiled
29+
def add(x, y):
30+
return x + y
31+
32+
class Spam:
33+
@Profiled
34+
def bar(self, x):
35+
print(self, x)
36+
37+
if __name__ == '__main__':
38+
add(2, 3)
39+
add(4, 5)
40+
print(add.ncalls)
41+
42+
s = Spam()
43+
s.bar(1)
44+
s.bar(2)
45+
s.bar(3)
46+
print(Spam.bar.ncalls)
47+

‎结构型模式-装饰者模式.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
# @Author : ydf
3+
# @Time : 2019/10/8 0008 18:24
4+
5+
"""
6+
无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法。
7+
 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法)
8+
 使用组合
9+
 使用继承
10+
与继承相比,通常应该优先选择组合,因为继承使得代码更难复用,继承关系是静态的,并且应用于整个类以及这个类的所有实例(请参考[GOF95,第31页]和网页[t.cn/RqrC8Yo])。
11+
设计模式为我们提供第四种可选方法,以支持动态地(运行时)扩展一个对象的功能,这种方法就是修饰器。修饰器(Decorator)模式能够以透明的方式(不会影响其他对象)动态地将功能添加到一个对象中(请参考[GOF95,第196页])。
12+
在许多编程语言中,使用子类化(继承)来实现修饰器模式(请参考[GOF95,第198页])。
13+
在Python中,我们可以(并且应该)使用内置的修饰器特性。一个Python修饰器就是对Python语法的一个特定改变,用于扩展一个类、方法或函数的行为,而无需使用继承。从实现的角度来说,
14+
Python修饰器是一个可调用对象(函数、方法、类),接受一个函数对象fin作为输入,并返回另一个函数对象 。这意味着可以将任何具有这些属性的可调用对象当作一个修饰器。在第1章和第2章中已经看到如何使用内置的property修饰器让一个方法表现为一个变量。在5.4节,我们将学习如何实现及使用我们自己的修饰器。
15+
修饰器模式和Python修饰器之间并不是一对一的等价关系。Python修饰器能做的实际上比修饰器模式多得多,其中之一就是实现修饰器模式
16+
"""
17+
from monkey_print2 import print
18+
19+
class Foo:
20+
def f1(self):
21+
print("original f1")
22+
23+
def f2(self):
24+
print("original f2")
25+
26+
27+
class Foo_decorator:
28+
def __init__(self, decoratee):
29+
self._decoratee = decoratee
30+
31+
def f1(self):
32+
print("before run f1")
33+
self._decoratee.f1()
34+
print("after run f1")
35+
36+
def __getattr__(self, name):
37+
return getattr(self._decoratee, name)
38+
39+
if __name__ == '__main__':
40+
u = Foo()
41+
v = Foo_decorator(u)
42+
v.f1()
43+
v.f2()

0 commit comments

Comments
 (0)
Please sign in to comment.