基于python的设计模式之创建型模型

设计模式(GOF):
每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计
设计模式四个基本要素:模式名称、问题、解决方法、效果

设计模式前戏:
对象/类
封装、继承、多态
接口:一个特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法
作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现
接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法

Python中接口的两种写法

 1 class Interface:
 2     def method(self,arg):
 3         raise NotImplementedError
 4 
 5 #抽象类不可以实例化
 6 from abc import abstractmethod,ABCMeta
 7 class Interface(metaclass=ABCMeta):
 8     @abstractmethod
 9     def method(self,arg):
10         pass

 

设计模式六大原则
开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
里氏(Liskov)替换原则:所有引用基类(父类)的方法必须能透明地使用其子类的对象。
依赖倒置原则:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。换言之,要针对接口编程,而不是针对实现编程。
接口隔离原则:使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。
迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用(解耦)。
单一职责原则:不要存在多于一个导致类变更的原因。通俗的说,即一个类只负责一项职责。

创建型模式:工厂方法模式,抽象工厂模式,创建者模式,原型模式,单例模式
结构型模式:适配器模式,桥模式,组合模式,装饰模式,外观模式,享元模式,代理模式
行为型模式:解释器模式,责任链模式,命令模式,迭代器模式,中介者模式,备忘录模式,观察者模式,状态模式,策略模式,访问者模式,模板方法模式

单例模式:
内容:保证一个类只有一个实例,并提供一个访问它的全局访问点。
角色:单例(Singleton)
适用场景:当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时
优点:对唯一实例的受控访问,单例相当于全局变量,但防止了命名空间被污染。
与单例模式功能相似的概念:全局变量、静态变量(方法)

例子:
#单例模式

 1 #单例模式
 2 #方法1 模块导入
 3 # site=ExtraAppSite()
 4 
 5 #方法2类方法
 6 # class Foo():
 7 #     _instance=None
 8 #     def __init__(self):
 9 #         pass
10 #     @classmethod
11 #     def get_instance(cls):
12 #         if cls._instance:
13 #             return cls._instance
14 #         else:
15 #             obj=cls()
16 #             cls._instance=obj
17 #             return obj
18 # a1=Foo.get_instance()
19 
20 #方法3__new__
21 # class Foo():
22 #     _instance=None
23 #     def __init__(self):
24 #         pass
25 #
26 #     def __new__(cls, *args, **kwargs): #创建对象
27 #         if cls._instance:
28 #             return cls._instance
29 #         else:
30 #             obj=object.__new__(cls, *args, **kwargs) #创建出来的对象传给init self里面
31 #             cls._instance=obj
32 #         return obj
33 #
34 #  #用户行为不需要改变
35 # obj=Foo()
36 # obj1=Foo()
37 # print(obj)
38 # print(obj1)
39 
40 #单例模式的用处
41     # 自定义CURD组件时,没有必要创建多个实例来浪费空间
42     # 发布文章,对于特殊字符的过滤KindEditor
43         # class Kind():
44         #     def __init__(self):
45         #         self.valid_tags=[
46         #             "a","div","h1"
47         #         ]
48         #     def valid(self,content):
49         #         pass
50         # obj=Kind()
51         # body=obj.valid("<html>")

 

简单工厂模式
内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。
角色:工厂角色(Creator),抽象产品角色(Product),具体产品角色(Concrete Product)
优点:隐藏了对象创建的实现细节,客户端不需要修改代码
缺点:违反了单一职责原则,将创建逻辑集中到一个工厂类里、当添加新产品时,需要修改工厂类代码,违反了开闭原则
例子:

 1 from abc import abstractmethod,ABCMeta
 2 class Payment(metaclass=ABCMeta):
 3     @abstractmethod
 4     def pay(self,money):
 5         pass
 6 
 7 class Alipay(Payment):
 8     def __init__(self,enable_yuebao=False):
 9         self.enable_yuebao=enable_yuebao
10 
11     def pay(self,money):
12         if self.enable_yuebao:
13             print('余额宝支付%s元'%money)
14         else:
15             print('支付宝支付%s元'%money)
16 
17 class ApplePay(Payment):
18     def pay(self,money):
19         print('余额宝支付%s元'%money)
20 
21 
22 class PaymentFactory:
23     def create_payment(self,method):
24         if method=='alipay':
25             return Alipay()
26         elif method=='yuhebao':
27             return Alipay(enable_yuebao=True)
28         elif method=='applepay':
29             return ApplePay()
30         else:
31             raise NameError(method)
32 
33 f=PaymentFactory()
34 p=f.create_payment('alipay')
35 p.pay(100)

 

工厂方法模式
内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。
角色:抽象工厂角色(Creator),具体工厂角色(Concrete Creator),抽象产品角色(Product),具体产品角色(Concrete Product)
工厂方法模式相比简单工厂模式将对每个具体产品都对应了一个具体工厂
实用场景:需要生产多种、大量复杂对象的时候、需要降低耦合度的时候、当系统中的产品种类需要经常扩展的时候。
优点:每个具体产品都对应一个具体工厂类,不需要修改工厂类代码、隐藏了对象创建的实现细节
缺点:每增加一个具体产品类,就必须增加一个相应的具体工厂类。
例子:

 1 from abc import abstractmethod,ABCMeta
 2 class Payment(metaclass=ABCMeta):
 3     @abstractmethod
 4     def pay(self, money):
 5         pass
 6 
 7 class Alipay(Payment):
 8     def pay(self, money):
 9         print('余额宝支付%s元' % money)
10 
11 class ApplePay(Payment):
12     def pay(self, money):
13         print('余额宝支付%s元' % money)
14 
15 
16 class PaymentFactory(metaclass=ABCMeta):
17     @abstractmethod
18     def create_payment(self):
19         pass
20 
21 
22 class AlipayFactory(PaymentFactory):
23     def create_payment(self):
24         return Alipay()
25 
26 class ApplePayFactory(PaymentFactory):
27     def create_payment(self):
28         return ApplePay()
29 
30 
31 af=AlipayFactory()
32 ali=af.create_payment()
33 ali.pay(120)

 

抽象工厂模式
内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。
例:生产一部手机,需要手机壳,CPU,操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。
角色:抽象工厂角色(Creator),具体工厂角色(Concrete Creator),抽象产品角色(Product),具体产品角色(Product),客户端(Client)
相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。
适用场景:系统要独立于产品创建与组合时、强调一系列相关的产品对象的设计以便进行联合使用时、提供一个产品类库,想隐藏产品的具体实现时。
优点:将客户端与类具体实现相分离、每个工厂创建一个完整的产品系列,使得易于交换产品系列、有利于产品的一致性(即产品之间的约束关系)
缺点:难以支持新种类的(抽象)产品
例子:

  1 from abc import abstractmethod,ABCMeta
  2 
  3 #抽象工厂
  4 class PhoneFactory(metaclass=ABCMeta):
  5     @abstractmethod
  6     def make_shell(self):
  7         pass
  8 
  9     @abstractmethod
 10     def make_cpu(self):
 11         pass
 12 
 13     @abstractmethod
 14     def make_os(self):
 15         pass
 16 
 17 #抽象产品
 18 class PhoneShell(metaclass=ABCMeta):
 19     @abstractmethod
 20     def show_shell(self):
 21         pass
 22 
 23 class OS(metaclass=ABCMeta):
 24     @abstractmethod
 25     def show_os(self):
 26         pass
 27 
 28 class CPU(metaclass=ABCMeta):
 29     @abstractmethod
 30     def show_cpu(self):
 31         pass
 32 
 33 
 34 #具体产品
 35 class SmallShell(PhoneShell):
 36     def show_shell(self):
 37         print('普通手机小手机壳')
 38 
 39 class BigShell(PhoneShell):
 40     def show_shell(self):
 41         print('普通手机大手机壳')
 42 
 43 class AppleShell(PhoneShell):
 44     def show_shell(self):
 45         print('苹果手机壳')
 46 
 47 class SnapDragonCPU(CPU):
 48     def show_cpu(self):
 49         print('骁龙CPU')
 50 
 51 class MediaTekCPU(CPU):
 52     def show_cpu(self):
 53         print('联发科CPU')
 54 
 55 class AppleCPU(CPU):
 56     def show_cpu(self):
 57         print('苹果CPU')
 58 
 59 class Android(OS):
 60     def show_os(self):
 61         print('Android系统')
 62 
 63 class IOS(OS):
 64     def show_os(self):
 65         print('iOS系统')
 66 
 67 #具体工厂
 68 class MiFactory(PhoneFactory):
 69     def make_cpu(self):
 70         return SnapDragonCPU()
 71 
 72     def make_os(self):
 73         return Android()
 74 
 75     def make_shell(self):
 76         return BigShell()
 77 
 78 
 79 class HuaweiFactory(PhoneFactory):
 80     def make_cpu(self):
 81         return MediaTekCPU()
 82 
 83     def make_os(self):
 84         return Android()
 85 
 86     def make_shell(self):
 87         return SmallShell()
 88 
 89 class IPhoneFactory(PhoneFactory):
 90     def make_cpu(self):
 91         return AppleCPU()
 92 
 93     def make_os(self):
 94         return IOS()
 95 
 96     def make_shell(self):
 97         return AppleShell()
 98 
 99 #客户端
100 class Phone:
101     def __init__(self,cpu,os,shell):
102         self.cpu=cpu
103         self.os=os
104         self.shell=shell
105 
106     def show_info(self):
107         print('手机信息:')
108         self.cpu.show_cpu()
109         self.os.show_os()
110         self.shell.show_shell()
111 
112 def make_phone(factory):
113     cpu=factory.make_cpu()
114     os=factory.make_os()
115     shell=factory.make_shell()
116     return Phone(cpu,os,shell)
117 
118 pl=make_phone(IPhoneFactory())
119 pl.show_info()

 

建造者模式
内容:将一个复杂对象的构建与它表示分离,使得同样的构建过程可以创建不同的表示。
角色:抽象建造者(Builder),具体建造者(Concrete Builder),指挥者(Director),产品(Product)
建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列产品对象。
适用场景:当创建复杂对象的算法(Director)应该独立于该对象的组成部分时,当构造过程允许被构造的对象有不同的表示时(不同Builder)。
优点:隐藏了一个产品的内部结构和装配过程、将构造代码与表示代码分开、可以对构造过程进行更精细的控制
例子:

 1 from abc import abstractmethod,ABCMeta
 2 class Player:
 3     def __init__(self,face=None,body=None,arm=None,leg=None):
 4         self.face=face
 5         self.body=body
 6         self.arm=arm
 7         self.leg=leg
 8 
 9     def __str__(self):
10         return "%s,%s,%s,%s"%(self.face,self.arm,self.body,self.leg)
11 
12 #建造者
13 class PlayerBuilder(metaclass=ABCMeta):
14     @abstractmethod
15     def build_face(self):
16         pass
17 
18     @abstractmethod
19     def build_arm(self):
20         pass
21 
22     @abstractmethod
23     def build_leg(self):
24         pass
25 
26     @abstractmethod
27     def build_body(self):
28         pass
29 
30     @abstractmethod
31     def get_player(self):
32         pass
33 
34 class BeautifulWomanBuilder(PlayerBuilder):
35     def __init__(self):
36         self.player=Player()
37 
38     def build_face(self):
39         self.player.face='漂亮脸蛋'
40 
41     def build_arm(self):
42         self.player.arm='细胳膊'
43 
44     def build_leg(self):
45         self.player.leg = '长腿'
46 
47     def build_body(self):
48         self.player.body = '细腰'
49 
50     def get_player(self):
51         return self.player
52 
53 
54 class PlayDirector:
55     def build_player(self,builder):
56         builder.build_body()
57         builder.build_arm()
58         builder.build_leg()
59         builder.build_face()
60         return builder.get_player()
61 
62 director=PlayDirector()
63 builder=BeautifulWomanBuilder()
64 p=director.build_player(builder)
65 print(p)

 

创建型模型小结
使用Abstract Factory、Prototype或Builder的设计甚至比使用Factory Method的那些设计更灵活,但它们也更加复杂。通常,设计以使用Factory Method开始,并且当设计者发现需要更大的灵活性时,设计便会向其他创建模式演化。当你在设计标准之间进行权衡的时候,了解多个模式可以给你提供更多的选择余地。
依赖于继承的创建型模式:工厂方法模式
依赖于组合的创建型模式:抽象工厂模式、创建者模式



转载于:https://www.cnblogs.com/tianlinger/p/9210005.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值