python設計模式-結構模式
阿新 • • 發佈:2020-08-16
III.結構模式
1.代理模式
-
代理模式,一個類代表另一個類功能,在代理模式中,我們建立具有現有物件的物件,以便向外界提供功能介面。
class SensitiveInfo: def __init__(self): self.users = ["nick","tom","ben","mike"] def read(self): print("the username is {}".format(' '.join(self.users))) def add(self,user): self.users.append(user) print("add user {}".format(user)) class Info: def __init__(self): self.protected = SensitiveInfo() self.secret = "123456" def read(self): self.protected.read() def add(self, user): sec = input('what is the secret? ') self.protected.add(user) if sec == self.secret else print("That's wrong!") def main(): info = Info() while True: print('1. read list |==| 2. add user |==| 3. quit') key = input('choose option: ') if key == '1': info.read() elif key == '2': name = input('choose username: ') info.add(name) elif key == '3': exit() else: print('unknown option: {}'.format(key)) if __name__ == '__main__': main()
2.外觀模式
- 隱藏系統複雜性,向客戶端提供一個客戶端可以訪問系統介面。向現有系統新增一個介面,來隱藏系統複雜性。這種模式涉及到一個單一的類,該類提供了客戶端請求的簡化方法和對現有系統類方法的委託呼叫。
class A: def run(self): print('A run') def jump(self): print('A jump') class B: def run(self): print('B run') def jump(self): print('B jump') class C: def run(self): print('C run') def jump(self): print('C jump') class Facade: def __init__(self): self.a = A() self.b = B() self.c = C() def run(self): for item in ("a","b","c"): obj = getattr(self,item) obj.run() def jump(self): for item in ("a","b","c"): getattr(self,item).jump() if __name__ == '__main__': facade = Facade() facade.run() facade.jump()
3.橋接模式
- 在python程式設計中,橋接指的是抽象部分和實體部分的連線,簡單來說是類和類例項化過程中連結。
class A: def run(self,name): print("my name is {}".format(name)) class B: def run(self, name): print("我的名字是:{}".format(name)) class Bridge: def __init__(self, ager, classname): self.ager = ager self.classname = classname def bridge_run(self): self.classname.run(self.ager) if __name__ == '__main__': test = Bridge('Tom', A()) test.bridge_run()
4.組合模式
- 用於把一組相似物件當作一個單一的物件,組合模式依據樹形結構來組合物件。您想表示物件的部分-整體層次結構(樹形結構)。 2、您希望使用者忽略組合物件與單個物件的不同,使用者將統一地使用組合結構中的所有物件。
class Company:
name = ''
def __init__(self, name):
self.name = name
def add(self, company):
pass
def remove(self, company):
pass
def display(self, depth):
pass
def line_of_duty(self): # 履行職責
pass
# Composite:公司類
class ConcreteCompany(Company):
childrenCompany = None
def __init__(self, name):
Company.__init__(self, name)
self.childrenCompany = []
def add(self, company):
self.childrenCompany.append(company)
def remove(self, company):
self.childrenCompany.remove(company)
def display(self, depth):
print('-' * depth + self.name)
for component in self.childrenCompany:
component.display(depth + 2)
def line_of_duty(self): # 履行職責
for component in self.childrenCompany:
component.line_of_duty()
# Leaf:具體職能部門
class HRDepartment(Company):
def __init__(self, name):
Company.__init__(self, name)
def display(self, depth):
print('-' * depth + self.name)
def line_of_duty(self): # 履行職責
print('%s\t員工招聘培訓管理' % self.name)
# Leaf:具體職能部門
class FinanceDepartment(Company):
def __init__(self, name):
Company.__init__(self, name)
def display(self, depth):
print('-' * depth + self.name)
def line_of_duty(self): # 履行職責
print('%s\t公司財務收支管理' % self.name)
if __name__ == '__main__':
root = ConcreteCompany('北京總公司')
root.add(HRDepartment('總公司人力資源部'))
root.add(FinanceDepartment('總公司財務部'))
comp = ConcreteCompany('華東分公司')
comp.add(HRDepartment('華東分公司人力資源部'))
comp.add(FinanceDepartment('華東分公司財務部'))
root.add(comp)
comp1 = ConcreteCompany('南京辦事處')
comp1.add(HRDepartment('南京辦事處人力資源部'))
comp1.add(FinanceDepartment('南京辦事處財務部'))
comp.add(comp1)
comp2 = ConcreteCompany('杭州辦事處')
comp2.add(HRDepartment('杭州辦事處人力資源部'))
comp2.add(FinanceDepartment('杭州辦事處財務部'))
comp.add(comp2)
print('-------公司結構圖-------')
root.display(1)
print('\n-------職責-------')
root.line_of_duty()
5.裝飾者模式--函式裝飾器
import time
from functools import wraps
def timethis(func):
'''
Decorator that reports the execution time.
'''
@wraps(func)
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(func.__name__, end - start)
return result
return wrapper
@timethis
def fun():
time.sleep(3)
return 1
if __name__ == '__main__':
fun()
6.裝飾者模式--類裝飾器
class Spam:
@profiled
def bar(self,x)
print(self,x)
- 我們想給一個物件新增額外功能,可以通過裝飾器,繼承或是組合方式,相比繼承,它會使程式碼更難去複用,繼承關係是靜態的。
# 修飾器裝飾
class Foo:
def f1(self):
print("original f1")
def f2(self):
print("original f2")
class Foo_decorator:
def __init__(self, decoratee):
self._decoratee = decoratee
def f1(self):
print("before run f1")
self._decoratee.f1()
print("after run f1")
def __getattr__(self, name):
return getattr(self._decoratee, name)
if __name__ == '__main__':
u = Foo()
v = Foo_decorator(u)
v.f1()
v.f2()
7.介面卡模式
- 做為兩個介面是否相容的橋樑,這種模式涉及到一個單一的類,該類負責加入獨立的或不相容的介面功能。舉個真實的例子,讀卡器是作為記憶體卡和筆記本之間的介面卡。您將記憶體卡插入讀卡器,再將讀卡器插入筆記本,這樣就可以通過筆記本來讀取記憶體卡。
class Dog:
def __init__(self, name):
self.name = name
def wangwang(self):
print('my name is' + self.name + '。。。汪汪汪。。。')
def dog_run(self):
print(f'{self.name} is running')
class Cat:
def __init__(self, name):
self.name = name
def miaomiao(self):
print('my name is' + self.name + '。。。喵喵喵。。。')
def cat_run(self):
print(f'{self.name} is running')
class Sheep:
def __init__(self, name):
self.name = name
def miemie(self):
print('my name is' + self.name + '。。。咩咩。。。')
def sheet_run(self):
print(f'{self.name} is running')
class Adapter:
def __init__(self, adapted_methods):
self.__dict__.update(adapted_methods)
def speak(self):
pass
def run(self):
pass
def main():
animals = []
dog = Dog('旺財')
cat = Cat('大臉貓')
sheep = Sheep('喜洋洋')
animals.append(Adapter({'speak': dog.wangwang, 'run': dog.dog_run}))
animals.append(Adapter({'speak': cat.miaomiao, 'run': cat.cat_run}))
animals.append(Adapter({'speak': sheep.miemie, 'run': sheep.sheet_run}))
for a in animals:
a.speak()
a.run()
if __name__ == '__main__':
main()