python16_day34【设计模式】
一、简单工厂模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/24 3 4 from abc import abstractmethod, ABCMeta 5 6 class Payment(metaclass=ABCMeta): 7 @abstractmethod 8 def pay(self, money): 9 pass 10 11 class Alipay(Payment): 12 def __init__(self, enable_yuebao=False): 13 self.enable_yuebao = enable_yuebao 14 15 def pay(self, money): 16 if self.enable_yuebao: 17 print("余额宝支付%s元" % money) 18 else: 19 print("支付宝支付%s元" % money) 20 21 22 class ApplePay(Payment): 23 def pay(self, money): 24 print("苹果支付%s元" % money) 25 26 27 class PaymentFactory: 28 def create_payment(self, method): 29 if method == "alipay": 30 return Alipay() 31 elif method == "applepay": 32 return ApplePay() 33 elif method == "yuebao": 34 return Alipay(enable_yuebao=True) 35 else: 36 raise NameError(method) 37 38 f = PaymentFactory() 39 p = f.create_payment("alipay") 40 p.pay(100)
二、工厂模式
1 from abc import abstractmethod, ABCMeta 2 3 4 class Payment(metaclass=ABCMeta): 5 @abstractmethod 6 def pay(self, money): 7 pass 8 9 10 class Alipay(Payment): 11 def pay(self, money): 12 print("支付宝支付%s元" % money) 13 14 15 class ApplePay(Payment): 16 def pay(self, money): 17 print("苹果支付%s元"%money) 18 19 20 class PaymentFactory(metaclass=ABCMeta): 21 @abstractmethod 22 def create_payment(self): 23 pass 24 25 26 class AlipayFactory(PaymentFactory): 27 def create_payment(self): 28 return Alipay() 29 30 class ApplePayFactory(PaymentFactory): 31 def create_payment(self): 32 return ApplePay() 33 34 35 36 37 # 用户输入 38 # 支付宝,120 39 40 af = AlipayFactory() 41 ali = af.create_payment() 42 ali.pay(120)
三、抽象工厂模式
1 rom abc import abstractmethod, ABCMeta 2 3 # ------抽象产品------ 4 class PhoneShell(metaclass=ABCMeta): 5 @abstractmethod 6 def show_shell(self): 7 pass 8 9 class CPU(metaclass=ABCMeta): 10 @abstractmethod 11 def show_cpu(self): 12 pass 13 14 class OS(metaclass=ABCMeta): 15 @abstractmethod 16 def show_os(self): 17 pass 18 19 20 # ------抽象工厂------ 21 22 class PhoneFactory(metaclass=ABCMeta): 23 @abstractmethod 24 def make_shell(self): 25 pass 26 27 @abstractmethod 28 def make_cpu(self): 29 pass 30 31 @abstractmethod 32 def make_os(self): 33 pass 34 35 36 # ------具体产品------ 37 38 39 class SmallShell(PhoneShell): 40 def show_shell(self): 41 print("普通手机小手机壳") 42 43 class BigShell(PhoneShell): 44 def show_shell(self): 45 print("普通手机大手机壳") 46 47 class AppleShell(PhoneShell): 48 def show_shell(self): 49 print("苹果手机壳") 50 51 52 class SnapDragonCPU(CPU): 53 def show_cpu(self): 54 print("骁龙CPU") 55 56 57 class MediaTekCPU(CPU): 58 def show_cpu(self): 59 print("联发科CPU") 60 61 62 class AppleCPU(CPU): 63 def show_cpu(self): 64 print("苹果CPU") 65 66 67 class Android(OS): 68 def show_os(self): 69 print("Android系统") 70 71 72 class IOS(OS): 73 def show_os(self): 74 print("iOS系统") 75 76 77 # ------具体工厂------ 78 79 class MiFactory(PhoneFactory): 80 def make_cpu(self): 81 return SnapDragonCPU() 82 83 def make_os(self): 84 return Android() 85 86 def make_shell(self): 87 return BigShell() 88 89 90 class HuaweiFactory(PhoneFactory): 91 def make_cpu(self): 92 return MediaTekCPU() 93 94 def make_os(self): 95 return Android() 96 97 def make_shell(self): 98 return SmallShell() 99 100 101 class IPhoneFactory(PhoneFactory): 102 def make_cpu(self): 103 return AppleCPU() 104 105 def make_os(self): 106 return IOS() 107 108 def make_shell(self): 109 return AppleShell() 110 111 112 # ------客户端------ 113 114 115 class Phone: 116 def __init__(self, cpu, os, shell): 117 self.cpu = cpu 118 self.os = os 119 self.shell = shell 120 121 def show_info(self): 122 print("手机信息:") 123 self.cpu.show_cpu() 124 self.os.show_os() 125 self.shell.show_shell() 126 127 128 def make_phone(factory): 129 cpu = factory.make_cpu() 130 os = factory.make_os() 131 shell = factory.make_shell() 132 return Phone(cpu, os, shell) 133 134 135 136 p1 = make_phone(HuaweiFactory()) 137 p1.show_info()
四、建筑者模式
1 from abc import abstractmethod, ABCMeta 2 3 #------产品------ 4 5 class Player: 6 def __init__(self, face=None, body=None, arm=None, leg=None): 7 self.face = face 8 self.arm = arm 9 self.leg = leg 10 self.body = body 11 12 def __str__(self): 13 return "%s, %s, %s, %s" % (self.face, self.arm, self.body, self.leg) 14 15 16 #------建造者------ 17 18 class PlayerBuilder(metaclass=ABCMeta): 19 @abstractmethod 20 def build_face(self): 21 pass 22 @abstractmethod 23 def build_arm(self): 24 pass 25 @abstractmethod 26 def build_leg(self): 27 pass 28 @abstractmethod 29 def build_body(self): 30 pass 31 @abstractmethod 32 def get_player(self): 33 pass 34 35 36 class BeautifulWomanBuilder(PlayerBuilder): 37 def __init__(self): 38 self.player = Player() 39 def build_face(self): 40 self.player.face = "漂亮脸蛋" 41 def build_arm(self): 42 self.player.arm="细胳膊" 43 def build_body(self): 44 self.player.body="细腰" 45 def build_leg(self): 46 self.player.leg="长腿" 47 def get_player(self): 48 return self.player 49 50 51 class PlayerDirector: 52 def build_player(self, builder): 53 builder.build_body() 54 builder.build_arm() 55 builder.build_leg() 56 builder.build_face() 57 return builder.get_player() 58 59 60 director = PlayerDirector() 61 builder = BeautifulWomanBuilder() 62 p = director.build_player(builder) 63 print(p)
五、单例模式
1 需要先看懂__new__这个方法 2 3 from abc import abstractmethod, ABCMeta 4 5 class Singleton(object): 6 def __new__(cls, *args, **kwargs): 7 # 第一次返回_instance这个实后,后续返回相同的。 8 if not hasattr(cls, "_instance"): 9 cls._instance = super(Singleton, cls).__new__(cls) 10 return cls._instance 11 12 13 14 class MyClass(Singleton): 15 def __init__(self, name): 16 self.name = name 17 18 19 a = MyClass("a") 20 21 print(a) 22 print(a.name) 23 24 b = MyClass('b') 25 # 26 print(b) 27 print(b.name) 28 b.name = 'xxx' 29 # 30 print(a) 31 print(a.name)
六、适配器模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/25 3 4 from abc import abstractmethod, ABCMeta 5 6 7 class Payment(metaclass=ABCMeta): 8 @abstractmethod 9 def pay(self, money): 10 raise NotImplementedError 11 12 13 class Alipay(Payment): 14 def pay(self, money): 15 print("支付宝支付%s元"%money) 16 17 18 class ApplePay(Payment): 19 def pay(self, money): 20 print("苹果支付%s元"%money) 21 22 #------待适配类------ 23 24 class WechatPay: 25 def huaqian(self, money): 26 print("微信支付%s元"%money) 27 28 # 方法一 29 #------类适配器------ 30 31 class RealWeChatPay(Payment, WechatPay): 32 def pay(self, money): 33 return self.huaqian(money) 34 35 # 方法二 36 #------对象适配器------ 37 class PayAdapter(Payment): 38 def __init__(self, payment): 39 self.payment = payment 40 41 def pay(self, money): 42 return self.payment.huaqian(money) 43 44 # client 45 RealWeChatPay().pay(100) 46 #PayAdapter(WechatPay()).pay(1000)
七、复合模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/25 3 4 from abc import abstractmethod, ABCMeta 5 6 class Graphic(metaclass=ABCMeta): 7 @abstractmethod 8 def draw(self): 9 pass 10 11 @abstractmethod 12 def add(self, graphic): 13 pass 14 15 def getchildren(self): 16 pass 17 18 # 图元 19 20 class Point(Graphic): 21 def __init__(self, x, y): 22 self.x = x 23 self.y = y 24 25 def draw(self): 26 print(self) 27 28 def add(self, graphic): 29 raise TypeError 30 31 def getchildren(self): 32 raise TypeError 33 34 def __str__(self): 35 return "点(%s, %s)" % (self.x, self.y) 36 37 38 class Line(Graphic): 39 def __init__(self, p1, p2): 40 self.p1 = p1 41 self.p2 = p2 42 43 def draw(self): 44 print(self) 45 46 def add(self, graphic): 47 raise TypeError 48 49 def getchildren(self): 50 raise TypeError 51 52 def __str__(self): 53 return "线段[%s, %s]" % (self.p1, self.p2) 54 55 56 class Picture(Graphic): 57 def __init__(self): 58 self.children = [] 59 60 def add(self, graphic): 61 self.children.append(graphic) 62 63 def getchildren(self): 64 return self.children 65 66 def draw(self): 67 print("------复合图形------") 68 for g in self.children: 69 g.draw() 70 print("------END------") 71 72 73 pic1 = Picture() 74 point = Point(2,3) 75 pic1.add(point) 76 pic1.add(Line(Point(1,2), Point(4,5))) 77 pic1.add(Line(Point(0,1), Point(2,1))) 78 79 pic2 = Picture() 80 pic2.add(Point(-2,-1)) 81 pic2.add(Line(Point(0,0), Point(1,1))) 82 83 pic = Picture() 84 pic.add(pic1) 85 pic.add(pic2) 86 87 pic.draw() 88 #pic1.draw() 89 #point.draw()
八、代理模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/26 3 4 from abc import ABCMeta, abstractmethod 5 6 class Subject(metaclass=ABCMeta): 7 @abstractmethod 8 def get_content(self): 9 pass 10 def set_content(self, content): 11 pass 12 13 14 class RealSubject(Subject): 15 def __init__(self, filename): 16 self.filename = filename 17 print("读取%s文件内容"%filename) 18 f = open(filename) 19 self.content = f.read() 20 f.close() 21 22 def get_content(self): 23 return self.content 24 25 def set_content(self, content): 26 f = open(self.filename, 'w') 27 f.write(content) 28 self.content = content 29 f.close() 30 31 32 33 class ProxyA(Subject): 34 def __init__(self, filename): 35 self.subj = RealSubject(filename) 36 37 def get_content(self): 38 return self.subj.get_content() 39 40 41 #---虚代理 42 class ProxyB(Subject): 43 def __init__(self, filename): 44 self.filename = filename 45 self.subj = None 46 47 def get_content(self): 48 if not self.subj: 49 self.subj = RealSubject(self.filename) 50 return self.subj.get_content() 51 52 x = ProxyB('abc.txt') 53 #print(x.get_content()) 54 55 56 57 58 class ProxyC(Subject): 59 def __init__(self, filename): 60 self.subj = RealSubject(filename) 61 62 def get_content(self): 63 self.subj.get_content() 64 65 def set_content(self, content): 66 raise PermissionError 67 68 # filename = "abc.txt" 69 # username = input() 70 # if username!="alex": 71 # p = ProxyC(filename) 72 # else: 73 # p = ProxyA(filename) 74 # 75 # print(p.get_content())
九、链式模式
1 from abc import ABCMeta, abstractmethod 2 3 class Handler(metaclass=ABCMeta): 4 @abstractmethod 5 def handle_leave(self, day): 6 pass 7 8 class GeneralManagerHandler(Handler): 9 def handle_leave(self, day): 10 if day < 10: 11 print("总经理批准%d天假"%day) 12 else: 13 print("呵呵") 14 15 class DepartmentManagerHandler(Handler): 16 def __init__(self): 17 self.successor = GeneralManagerHandler() 18 def handle_leave(self, day): 19 if day < 7: 20 print("部门经理批准%d天假"%day) 21 else: 22 print("部门经理无权准假") 23 self.successor.handle_leave(day) 24 25 26 class ProjectDirectorHandler(Handler): 27 def __init__(self): 28 self.successor = DepartmentManagerHandler() 29 def handle_leave(self, day): 30 if day < 3: 31 print("项目主管批准%d天假"%day) 32 else: 33 print("项目主管无权准假") 34 self.successor.handle_leave(day) 35 36 37 day = 9 38 h = ProjectDirectorHandler() 39 h.handle_leave(day)
十、迭代模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/27 3 4 5 class LinkList: 6 """链表 头结点保存链表的长度""" 7 class Node: 8 def __init__(self, item=None): 9 self.item = item 10 self.next = None 11 12 class LinkListIterator: 13 def __init__(self, node): 14 self.node = node 15 def __next__(self): 16 if self.node: 17 cur_node = self.node 18 self.node = cur_node.next 19 return cur_node.item 20 else: 21 raise StopIteration 22 def __iter__(self): 23 return self 24 25 def __init__(self, iterable=None): 26 self.head = LinkList.Node(0) 27 self.tail = self.head 28 self.extend(iterable) 29 30 def append(self, obj): 31 s = LinkList.Node(obj) 32 self.tail.next = s 33 self.tail = s 34 35 def extend(self, iterable): 36 for obj in iterable: 37 self.append(obj) 38 self.head.item += len(iterable) 39 40 def __iter__(self): 41 return self.LinkListIterator(self.head.next) 42 43 def __len__(self): 44 return self.head.item 45 46 def __str__(self): 47 return "<<" + ", ".join(map(str, self)) + ">>" 48 49 50 li = [i for i in range(100)] 51 lk = LinkList(li) 52 print(lk)
十一、观察者模式(发布订阅)
1 # coding : utf-8 2 # create by ztypl on 2017/5/27 3 4 from abc import ABCMeta, abstractmethod 5 6 class Observer(metaclass=ABCMeta): 7 @abstractmethod 8 def update(self, notice): 9 pass 10 11 12 class Notice: 13 def __init__(self): 14 self.observers = [] 15 16 def attach(self, obs): 17 self.observers.append(obs) 18 19 def detach(self, obs): 20 self.observers.remove(obs) 21 obs.company_info=None 22 23 def notify(self): 24 for obj in self.observers: 25 print("---", type(self)) 26 obj.update(self) #这个self是ManagerNotice对象 27 28 class ManagerNotice(Notice): 29 def __init__(self, company_info=None): 30 super().__init__() 31 self.__company_info = company_info 32 33 @property 34 def company_info(self): 35 return self.__company_info 36 37 @company_info.setter 38 def company_info(self, info): 39 self.__company_info = info 40 self.notify() 41 42 43 class Manager(Observer): 44 def __init__(self): 45 self.company_info = None 46 47 def update(self, noti): 48 self.company_info = noti.company_info # 拿到最新消息保存到对象中(alex,wusir) 49 50 51 notice = ManagerNotice() 52 53 alex = Manager() 54 wusir = Manager() 55 56 # print(alex.company_info) 57 # print(wusir.company_info) 58 59 notice.attach(alex) 60 notice.attach(wusir) 61 # 62 notice.company_info="公司运行良好" 63 # 64 print(alex.company_info) 65 print(wusir.company_info) 66 67 notice.company_info="公司将要上市" 68 # 69 print(alex.company_info) 70 print(wusir.company_info) 71 # # 72 notice.detach(wusir) 73 # # # 74 notice.company_info="公司要破产了,赶快跑路" 75 # # 76 print(alex.company_info) 77 print(wusir.company_info)
十二、策略模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/27 3 4 from abc import ABCMeta, abstractmethod 5 import random 6 7 class Sort(metaclass=ABCMeta): 8 @abstractmethod 9 def sort(self, data): 10 pass 11 12 13 class QuickSort(Sort): 14 def quick_sort(self, data, left, right): 15 if left < right: 16 mid = self.partition(data, left, right) 17 self.quick_sort(data, left, mid - 1) 18 self.quick_sort(data, mid + 1, right) 19 20 def partition(self, data, left, right): 21 tmp = data[left] 22 while left < right: 23 while left < right and data[right] >= tmp: 24 right -= 1 25 data[left] = data[right] 26 while left < right and data[left] <= tmp: 27 left += 1 28 data[right] = data[left] 29 data[left] = tmp 30 return left 31 32 def sort(self, data): 33 print("快速排序") 34 return self.quick_sort(data, 0, len(data) - 1) 35 36 37 class MergeSort(Sort): 38 def merge(self, data, low, mid, high): 39 i = low 40 j = mid + 1 41 ltmp = [] 42 while i <= mid and j <= high: 43 if data[i] <= data[j]: 44 ltmp.append(data[i]) 45 i += 1 46 else: 47 ltmp.append(data[j]) 48 j += 1 49 50 while i <= mid: 51 ltmp.append(data[i]) 52 i += 1 53 54 while j <= high: 55 ltmp.append(data[j]) 56 j += 1 57 58 data[low:high + 1] = ltmp 59 60 61 def merge_sort(self, data, low, high): 62 if low < high: 63 mid = (low + high) // 2 64 self.merge_sort(data, low, mid) 65 self.merge_sort(data, mid + 1, high) 66 self.merge(data, low, mid, high) 67 68 def sort(self, data): 69 print("归并排序") 70 return self.merge_sort(data, 0, len(data) - 1) 71 72 73 class Context: 74 def __init__(self, data, strategy=None): 75 self.data = data 76 self.strategy = strategy 77 78 def set_strategy(self, strategy): 79 self.strategy = strategy 80 81 def do_strategy(self): 82 if self.strategy: 83 self.strategy.sort(self.data) 84 else: 85 raise TypeError 86 87 88 li = list(range(100000)) 89 random.shuffle(li) 90 91 92 context = Context(li, MergeSort()) 93 context.do_strategy() 94 #print(context.data) 95 96 random.shuffle(context.data) 97 98 context.set_strategy(QuickSort()) 99 context.do_strategy()
十三、模板方法模式
1 # coding : utf-8 2 # create by ztypl on 2017/5/27 3 4 from abc import ABCMeta, abstractmethod 5 6 7 class IOHandler(metaclass=ABCMeta): 8 @abstractmethod 9 def open(self, name): 10 pass 11 @abstractmethod 12 def deal(self, change): 13 pass 14 @abstractmethod 15 def close(self): 16 pass 17 def process(self, name, change): 18 self.open(name) 19 self.deal(change) 20 self.close() 21 22 class FileHandler(IOHandler): 23 def open(self, name): 24 self.file = open(name,"w") 25 26 def deal(self, change): 27 self.file.write(change) 28 29 def close(self): 30 self.file.close() 31 32 33 f = FileHandler() 34 f.process("abc.txt", "Hello World")