对软件设计中广泛存在(反复出现)的各类问题,所提出的解决方案。每个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计。
就是为了解决面向对象系统中重要和重复的设计封装在一块儿的一种代码实现框架,可使得代码更加易于扩展和调用。 算法
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()