對軟件設計中廣泛存在(反覆出現)的各類問題,所提出的解決方案。每個設計模式系統地命名、解釋和評價了面向對象系統中一個重要的和重複出現的設計。
就是爲了解決面向對象系統中重要和重複的設計封裝在一塊兒的一種代碼實現框架,可使得代碼更加易於擴展和調用。 算法
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # abstract class # 抽象產品角色 @abstractmethod def pay(self, money): pass class Alipay(Payment): # 抽象產品角色 def __init__(self, use_huabei=False): self.use_huabei = use_huabei def pay(self, money): if self.use_huabei: print("花唄支付%d元." % money) else: print("支付寶餘額支付%d元." % money) class WechatPay(Payment): # 抽象產品角色 def pay(self, money): print("微信支付%d元." % money) class PaymentFactory: #工廠角色 def create_payment(self, method): if method == 'alipay': return Alipay() elif method == 'wechat': return WechatPay() elif method == 'huabei': return Alipay(use_huabei=True) else: raise TypeError("No such payment named %s" % method) # client pf = PaymentFactory() p = pf.create_payment('huabei') p.pay(100)
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # 抽象產品 # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): # 具體產品 def __init__(self, use_huabei=False): self.use_huaei = use_huabei def pay(self, money): if self.use_huaei: print("花唄支付%d元." % money) else: print("支付寶餘額支付%d元." % money) class WechatPay(Payment): # 具體產品 def pay(self, money): print("微信支付%d元." % money) class PaymentFactory(metaclass=ABCMeta): # 抽象工廠 @abstractmethod def create_payment(self): pass class AlipayFactory(PaymentFactory): # 具體工廠 def create_payment(self): return Alipay() class WechatPayFactory(PaymentFactory): # 具體工廠 def create_payment(self): return WechatPay() class HuabeiFactory(PaymentFactory): # 具體工廠 def create_payment(self): return Alipay(use_huabei=True) # client pf = HuabeiFactory() p = pf.create_payment() p.pay(100) #若是要新增支付方式 class BankPay(Payment): # 具體產品 def pay(self, money): print("銀行卡支付%d元." % money) class BankPayFactory(PaymentFactory): # 具體工廠 def create_payment(self): return BankPay() bf = BankPayFactory() b = bf.create_payment() b.pay(200)
from abc import abstractmethod, ABCMeta # ------抽象產品------ class PhoneShell(metaclass=ABCMeta): @abstractmethod def show_shell(self): pass class CPU(metaclass=ABCMeta): @abstractmethod def show_cpu(self): pass class OS(metaclass=ABCMeta): @abstractmethod def show_os(self): pass # ------抽象工廠------ class PhoneFactory(metaclass=ABCMeta): @abstractmethod def make_shell(self): pass @abstractmethod def make_cpu(self): pass @abstractmethod def make_os(self): pass # ------具體產品------ class SmallShell(PhoneShell): def show_shell(self): print("普通手機小手機殼") class BigShell(PhoneShell): def show_shell(self): print("普通手機大手機殼") class AppleShell(PhoneShell): def show_shell(self): print("蘋果手機殼") class SnapDragonCPU(CPU): def show_cpu(self): print("驍龍CPU") class MediaTekCPU(CPU): def show_cpu(self): print("聯發科CPU") class AppleCPU(CPU): def show_cpu(self): print("蘋果CPU") class Android(OS): def show_os(self): print("Android系統") class IOS(OS): def show_os(self): print("iOS系統") # ------具體工廠------ class MiFactory(PhoneFactory): def make_cpu(self): return SnapDragonCPU() def make_os(self): return Android() def make_shell(self): return BigShell() class HuaweiFactory(PhoneFactory): def make_cpu(self): return MediaTekCPU() def make_os(self): return Android() def make_shell(self): return SmallShell() class IPhoneFactory(PhoneFactory): def make_cpu(self): return AppleCPU() def make_os(self): return IOS() def make_shell(self): return AppleShell() # ------客戶端------ class Phone: def __init__(self, cpu, os, shell): self.cpu = cpu self.os = os self.shell = shell def show_info(self): print("手機信息:") self.cpu.show_cpu() self.os.show_os() self.shell.show_shell() def make_phone(factory): cpu = factory.make_cpu() os = factory.make_os() shell = factory.make_shell() return Phone(cpu, os, shell) p1 = make_phone(IPhoneFactory()) p1.show_info()
from abc import ABCMeta, abstractmethod #------產品------ class Player: def __init__(self, face=None, body=None, arm=None, leg=None): self.face = face self.body = body self.arm = arm self.leg = leg def __str__(self): return "%s, %s, %s, %s" % (self.face, self.body, self.arm, self.leg) #------建造者------ class PlayerBuilder(metaclass=ABCMeta): @abstractmethod def build_face(self): pass @abstractmethod def build_body(self): pass @abstractmethod def build_arm(self): pass @abstractmethod def build_leg(self): pass #------具體建造者------ class SexyGirlBuilder(PlayerBuilder): def __init__(self): self.player = Player() def build_face(self): self.player.face = "漂亮臉蛋" def build_body(self): self.player.body = "苗條" def build_arm(self): self.player.arm = "漂亮胳膊" def build_leg(self): self.player.leg = "大長腿" class Monster(PlayerBuilder): def __init__(self): self.player = Player() def build_face(self): self.player.face = "怪獸臉" def build_body(self): self.player.body = "怪獸身材" def build_arm(self): self.player.arm = "長毛的胳膊" def build_leg(self): self.player.leg = "長毛的腿" #------指揮者------ class PlayerDirector: # 控制組裝順序 def build_player(self, builder): builder.build_body() builder.build_face() builder.build_arm() builder.build_leg() return builder.player # client builder = Monster() director = PlayerDirector() p = director.build_player(builder) print(p)
# mysingleton.py class My_Singleton(object): def foo(self): pass my_singleton = My_Singleton() #將上面的代碼保存在文件 mysingleton.py 中,而後這樣使用: from mysingleton import my_singleton my_singleton.foo()
#1.不能支持多線程的單例模式 class Singleton(object): @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, '_instance'): Singleton._instance = Singleton() return Singleton._instance a = Singleton.instance() b = Singleton.instance() print(a == b) # True #2.加上多線程(過渡版-有問題) import time class Singleton(object): def __init__(self): time.sleep(1) @classmethod def instance(cls,*args,**kwargs): if not hasattr(Singleton,'_instance'): Singleton._instance=Singleton() return Singleton._instance import threading def task(): obj = Singleton.instance() print(obj) for i in range(10): t=threading.Thread(target=task) t.start() """ <__main__.Singleton object at 0x0000000001313828> <__main__.Singleton object at 0x0000000001313748> <__main__.Singleton object at 0x0000000001313908> ... """ #三、解決上面存在的問題,實現支持多線程的單列模式: import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls,*args,**kwargs): with cls._instance_lock: if not hasattr(Singleton,'_instance'): Singleton._instance=Singleton() return Singleton._instance return Singleton._instance def task(): obj = Singleton.instance() print(obj) for i in range(10): t=threading.Thread(target=task) t.start() """ <__main__.Singleton object at 0x00000000010B8278> <__main__.Singleton object at 0x00000000010B8278> <__main__.Singleton object at 0x00000000010B8278> ... """ ####問題:建立實例只能調用Singleton.instance()來調用,不能用Singleton()來實現
import threading class Singleton(): def __init__(self,name): self.name=name _instance_lock = threading.Lock() def __new__(cls, *args, **kwargs): with cls._instance_lock: if not hasattr(cls,'_instance'): cls._instance = super().__new__(cls) return cls._instance def task(i): Singleton(i) print(id(Singleton(i))) if __name__ == '__main__': for i in range(10): t = threading.Thread(target=task, args=(i,)) t.start()
""" 對象是類建立,建立對象時候類的__init__方法自動執行,對象()執行類的 __call__ 方法 類是type建立,建立類時候type的__init__方法自動執行,類() 執行type的 __call__方法(類的__new__方法,類的__init__方法) obj = Foo() 第1步: 執行type的 __init__ 方法【類是type的對象】 第2步: 執行type的 __call__ 方法 第3步:調用 Foo類(是type的對象)的 __new__方法,用於建立對象。 第4步:調用 Foo類(是type的對象)的 __init__方法,用於對對象初始化。 obj() 執行 Foo 的__call__方法 class SingletonType(type): def __init__(self,*args,**kwargs): print(1) super(SingletonType,self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): print(2) obj = cls.__new__(cls,*args, **kwargs) cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj) return obj class Foo(metaclass=SingletonType): def __init__(self,name): print(4) self.name = name def __new__(cls, *args, **kwargs): print(3) return object.__new__(cls) def __call__(self, *args, **kwargs): print(5) print(self.name) obj1 = Foo('name') # 1 2 3 4 obj1() # 5 name 執行 Foo 的__call__方法 """ import threading class Singleton(type): _instance_lock=threading.Lock() def __call__(cls, *args, **kwargs): with cls._instance_lock: if not hasattr(cls,'_instance'): cls._instance=super(Singleton, cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=Singleton): def __init__(self,name): self.name=name obj1 = Foo('name') obj2 = Foo('name') print(obj1==obj2) #true
from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): # abstract class @abstractmethod def pay(self, money): pass class Alipay(Payment): def pay(self, money): print("支付寶支付%d元." % money) class WechatPay(Payment): def pay(self, money): print("微信支付%d元." % money) #------待適配的類----- class BankPay: def cost(self, money): print("銀聯支付%d元." % money) #------待適配的類----- class ApplePay: def cost(self, money): print("蘋果支付%d元." % money) #------類適配器------ # class NewBankPay(Payment, BankPay): # def pay(self, money): # self.cost(money) #------類適配器------ # class NewApplePay(Payment, ApplePay): # def pay(self, money): # self.cost(money) #-----對象適配器----- class PaymentAdapter(Payment): def __init__(self, payment): self.payment = payment def pay(self, money): self.payment.cost(money) #NewBankPay().pay(100) p = PaymentAdapter(BankPay()) p.pay(100) # 組合 # class A: # pass # # class B: # def __init__(self): # self.a = A()
from abc import ABCMeta, abstractmethod #------維度1------ class Shape(metaclass=ABCMeta): def __init__(self, color): self.color = color @abstractmethod def draw(self): pass #------維度2------ class Color(metaclass=ABCMeta): @abstractmethod def paint(self, shape): pass class Rectangle(Shape): name = "長方形" def draw(self): # 長方形邏輯 self.color.paint(self) class Circle(Shape): name = "圓形" def draw(self): # 圓形邏輯 self.color.paint(self) class Line(Shape): name = "直線" def draw(self): # 直線邏輯 self.color.paint(self) class Red(Color): def paint(self, shape): print("紅色的%s" % shape.name) class Green(Color): def paint(self, shape): print("綠色的%s" % shape.name) class Blue(Color): def paint(self, shape): print("藍色的%s" % shape.name) shape = Line(Blue()) shape.draw() shape2 = Circle(Green()) shape2.draw()
from abc import ABCMeta, abstractmethod # 抽象組件 class Graphic(metaclass=ABCMeta): @abstractmethod def draw(self): pass # 葉子組件 class Point(Graphic): def __init__(self, x, y): self.x = x self.y = y def __str__(self): return "點(%s, %s)" % (self.x, self.y) def draw(self): print(str(self)) # 葉子組件 class Line(Graphic): def __init__(self, p1, p2): self.p1 = p1 self.p2 = p2 def __str__(self): return "線段[%s, %s]" % (self.p1, self.p2) def draw(self): print(str(self)) # 複合組件 class Picture(Graphic): def __init__(self, iterable): self.children = [] for g in iterable: self.add(g) def add(self, graphic): self.children.append(graphic) def draw(self): print("------複合圖形------") for g in self.children: g.draw() print("------複合圖形------") p1 = Point(2,3) l1 = Line(Point(3,4), Point(6,7)) l2 = Line(Point(1,5), Point(2,8)) pic1 = Picture([p1, l1, l2]) p2 = Point(4,4) l3 = Line(Point(1,1), Point(0,0)) pic2 = Picture([p2, l3]) pic = Picture([pic1, pic2]) pic.draw()
class CPU: def run(self): print("CPU開始運行") def stop(self): print("CPU中止運行") class Disk: def run(self): print("硬盤開始工做") def stop(self): print("硬盤中止工做") class Memory: def run(self): print("內存通電") def stop(self): print("內存斷電") class Computer: # Facade def __init__(self): self.cpu = CPU() self.disk = Disk() self.memory = Memory() def run(self): self.cpu.run() self.disk.run() self.memory.run() def stop(self): self.cpu.stop() self.disk.stop() self.memory.stop() # Client computer = Computer() computer.run() computer.stop()
from abc import ABCMeta, abstractmethod #抽象實體 class Subject(metaclass=ABCMeta): @abstractmethod def get_content(self): pass @abstractmethod def set_content(self, content): pass #實體 class RealSubject(Subject): def __init__(self, filename): self.filename = filename f = open(filename, 'r', encoding='utf-8') print("讀取文件內容") self.content = f.read() f.close() def get_content(self): return self.content def set_content(self, content): f = open(self.filename, 'w', encoding='utf-8') f.write(content) f.close() #遠程代理 class RemoteProxy(Subject): def __init__(self,filename): self.subj =RealSubject(filename) def get_content(self): return self.subj.get_content() #虛代理 class VirtualProxy(Subject): def __init__(self, filename): self.filename = filename self.subj = None def get_content(self): if not self.subj: self.subj = RealSubject(self.filename) return self.subj.get_content() def set_content(self, content): if not subj: self.subj = RealSubject(self.filename) return self.subj.set_content(content) #保護代理 class ProtectedProxy(Subject): def __init__(self, filename): self.subj = RealSubject(filename) def get_content(self): return self.subj.get_content() def set_content(self, content): raise PermissionError("無寫入權限") #subj = RealSubject("test.txt") #subj.get_content() subj = ProtectedProxy("test.txt") print(subj.get_content()) subj.set_content("abc")
from abc import ABCMeta, abstractmethod class Handler(metaclass=ABCMeta): @abstractmethod def handle_leave(self, day): pass class GeneralManager(Handler): def handle_leave(self, day): if day <= 10: print("總經理准假%d天" % day) else: print("你仍是辭職吧") class DepartmentManager(Handler): def __init__(self): self.next = GeneralManager() def handle_leave(self, day): if day <= 5: print("部門經理准假%s天" % day) else: print("部門經理職權不足") self.next.handle_leave(day) class ProjectDirector(Handler): def __init__(self): self.next = DepartmentManager() def handle_leave(self, day): if day <= 3: print("項目主管准假%d天" % day) else: print("項目主管職權不足") self.next.handle_leave(day) # Client day = 12 h = ProjectDirector() h.handle_leave(day)
from abc import ABCMeta, abstractmethod #--模仿js事件處理 class Handler(metaclass=ABCMeta): @abstractmethod def add_event(self,func): pass @abstractmethod def handler(self): pass class BodyHandler(Handler): def __init__(self): self.func = None def add_event(self,func): self.func = func def handler(self): if self.func: return self.func() else: print('已是最後一級,沒法處理') class ElementHandler(Handler): def __init__(self,successor): self.func = None self.successor = successor def add_event(self,func): self.func = func def handler(self): if self.func: return self.func() else: return self.successor.handler() #客戶端 body = {'type': 'body', 'name': 'body', 'children': [], 'father': None} div = {'type': 'div', 'name': 'div', 'children': [], 'father': body} a = {'type': 'a', 'name': 'a', 'children': [], 'father': div} body['children'] = div div['children'] = a body['event_handler'] = BodyHandler() div['event_handler'] = ElementHandler(div['father']['event_handler']) a['event_handler'] = ElementHandler(a['father']['event_handler']) def attach_event(element,func): element['event_handler'].add_event(func) #測試 def func_div(): print("這是給div的函數") def func_a(): print("這是給a的函數") def func_body(): print("這是給body的函數") attach_event(div,func_div) #attach_event(a,func_a) attach_event(body,func_body) a['event_handler'].handler()
from abc import ABCMeta, abstractmethod class Observer(metaclass=ABCMeta): # 抽象訂閱者 @abstractmethod def update(self, notice): # notice 是一個Notice類的對象 pass class Notice: # 抽象發佈者 def __init__(self): self.observers = [] def attach(self, obs): self.observers.append(obs) def detach(self, obs): self.observers.remove(obs) def notify(self): # 推送 for obs in self.observers: obs.update(self) class StaffNotice(Notice): # 具體發佈者 def __init__(self, company_info=None): super().__init__() self.__company_info = company_info @property def company_info(self): return self.__company_info @company_info.setter def company_info(self, info): self.__company_info = info self.notify() # 推送 class Staff(Observer): # 具體訂閱者 def __init__(self): self.company_info = None def update(self, notice): self.company_info = notice.company_info # Client notice = StaffNotice("初始公司信息") s1 = Staff() s2 = Staff() notice.attach(s1) notice.attach(s2) notice.company_info = "公司今年業績很是好,給你們發獎金!!!" print(s1.company_info) print(s2.company_info) notice.detach(s2) notice.company_info = "公司明天放假!!!" print(s1.company_info) print(s2.company_info)
from abc import ABCMeta,abstractmethod #抽象策略 class Strategy(metaclass=ABCMeta): @abstractmethod def execute(self, data): pass #具體策略 class FastStrategy(Strategy): def execute(self, data): print("用較快的策略處理%s" % data) #具體策略 class SlowStrategy(Strategy): def execute(self, data): print("用較慢的策略處理%s" % data) #上下文 class Context: def __init__(self, strategy, data): self.data = data self.strategy = strategy def set_strategy(self, strategy): self.strategy = strategy def do_strategy(self): self.strategy.execute(self.data) # Client data = "[...]" s1 = FastStrategy() s2 = SlowStrategy() context = Context(s1, data) context.do_strategy() context.set_strategy(s2) context.do_strategy()
from abc import ABCMeta, abstractmethod from time import sleep #----抽象類----- class Window(metaclass=ABCMeta): @abstractmethod def start(self): pass @abstractmethod def repaint(self): pass @abstractmethod def stop(self): # 原子操做/鉤子操做 pass # 在父類中定義了子類的行爲 def run(self): # 模板方法 self.start() while True: try: self.repaint() sleep(1) except KeyboardInterrupt: break self.stop() #子類中只須要實現部分算法,而不須要實現全部的邏輯 #-----具體類-------- class MyWindow(Window): def __init__(self, msg): self.msg = msg def start(self): print("窗口開始運行") def stop(self): print("窗口結束運行") def repaint(self): print(self.msg) MyWindow("Hello...").run()