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

设计模式(GOF):

每一个设计模式系统地命名、解释和评价了面向对象系统中一个重要的和重复出现的设计

设计模式四个基本要素:模式名称、问题、解决方法、效果

设计模式前戏:

对象/类

封装、继承、多态

接口:一个特殊的类,声明了若干方法,要求继承该接口的类必须实现这些方法

作用:限制继承接口的类的方法的名称及调用方式;隐藏了类的内部实现

接口就是一种抽象的基类(父类),限制继承它的类必须实现接口中定义的某些方法

Python中接口的两种写法

1 classInterface:2 defmethod(self,arg):3 raiseNotImplementedError4

5 #抽象类不可以实例化

6 from abc importabstractmethod,ABCMeta7 class Interface(metaclass=ABCMeta):8 @abstractmethod9 defmethod(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("")

简单工厂模式

内容:不直接向客户端暴露对象创建的实现细节,而是通过一个工厂类来负责创建产品类的实例。

角色:工厂角色(Creator),抽象产品角色(Product),具体产品角色(Concrete Product)

优点:隐藏了对象创建的实现细节,客户端不需要修改代码

缺点:违反了单一职责原则,将创建逻辑集中到一个工厂类里、当添加新产品时,需要修改工厂类代码,违反了开闭原则

例子:

1 from abc importabstractmethod,ABCMeta2 class Payment(metaclass=ABCMeta):3 @abstractmethod4 defpay(self,money):5 pass

6

7 classAlipay(Payment):8 def __init__(self,enable_yuebao=False):9 self.enable_yuebao=enable_yuebao10

11 defpay(self,money):12 ifself.enable_yuebao:13 print('余额宝支付%s元'%money)14 else:15 print('支付宝支付%s元'%money)16

17 classApplePay(Payment):18 defpay(self,money):19 print('余额宝支付%s元'%money)20

21

22 classPaymentFactory:23 defcreate_payment(self,method):24 if method=='alipay':25 returnAlipay()26 elif method=='yuhebao':27 return Alipay(enable_yuebao=True)28 elif method=='applepay':29 returnApplePay()30 else:31 raiseNameError(method)32

33 f=PaymentFactory()34 p=f.create_payment('alipay')35 p.pay(100)

工厂方法模式

内容:定义一个用于创建对象的接口(工厂接口),让子类决定实例化哪一个产品类。

角色:抽象工厂角色(Creator),具体工厂角色(Concrete Creator),抽象产品角色(Product),具体产品角色(Concrete Product)

工厂方法模式相比简单工厂模式将对每个具体产品都对应了一个具体工厂

实用场景:需要生产多种、大量复杂对象的时候、需要降低耦合度的时候、当系统中的产品种类需要经常扩展的时候。

优点:每个具体产品都对应一个具体工厂类,不需要修改工厂类代码、隐藏了对象创建的实现细节

缺点:每增加一个具体产品类,就必须增加一个相应的具体工厂类。

例子:

1 from abc importabstractmethod,ABCMeta2 class Payment(metaclass=ABCMeta):3 @abstractmethod4 defpay(self, money):5 pass

6

7 classAlipay(Payment):8 defpay(self, money):9 print('余额宝支付%s元' %money)10

11 classApplePay(Payment):12 defpay(self, money):13 print('余额宝支付%s元' %money)14

15

16 class PaymentFactory(metaclass=ABCMeta):17 @abstractmethod18 defcreate_payment(self):19 pass

20

21

22 classAlipayFactory(PaymentFactory):23 defcreate_payment(self):24 returnAlipay()25

26 classApplePayFactory(PaymentFactory):27 defcreate_payment(self):28 returnApplePay()29

30

31 af=AlipayFactory()32 ali=af.create_payment()33 ali.pay(120)

抽象工厂模式

内容:定义一个工厂类接口,让工厂子类来创建一系列相关或相互依赖的对象。

例:生产一部手机,需要手机壳,CPU,操作系统三类对象进行组装,其中每类对象都有不同的种类。对每个具体工厂,分别生产一部手机所需要的三个对象。

角色:抽象工厂角色(Creator),具体工厂角色(Concrete Creator),抽象产品角色(Product),具体产品角色(Product),客户端(Client)

相比工厂方法模式,抽象工厂模式中的每个具体工厂都生产一套产品。

适用场景:系统要独立于产品创建与组合时、强调一系列相关的产品对象的设计以便进行联合使用时、提供一个产品类库,想隐藏产品的具体实现时。

优点:将客户端与类具体实现相分离、每个工厂创建一个完整的产品系列,使得易于交换产品系列、有利于产品的一致性(即产品之间的约束关系)

缺点:难以支持新种类的(抽象)产品

例子:

1 from abc importabstractmethod,ABCMeta2

3 #抽象工厂

4 class PhoneFactory(metaclass=ABCMeta):5 @abstractmethod6 defmake_shell(self):7 pass

8

9 @abstractmethod10 defmake_cpu(self):11 pass

12

13 @abstractmethod14 defmake_os(self):15 pass

16

17 #抽象产品

18 class PhoneShell(metaclass=ABCMeta):19 @abstractmethod20 defshow_shell(self):21 pass

22

23 class OS(metaclass=ABCMeta):24 @abstractmethod25 defshow_os(self):26 pass

27

28 class CPU(metaclass=ABCMeta):29 @abstractmethod30 defshow_cpu(self):31 pass

32

33

34 #具体产品

35 classSmallShell(PhoneShell):36 defshow_shell(self):37 print('普通手机小手机壳')38

39 classBigShell(PhoneShell):40 defshow_shell(self):41 print('普通手机大手机壳')42

43 classAppleShell(PhoneShell):44 defshow_shell(self):45 print('苹果手机壳')46

47 classSnapDragonCPU(CPU):48 defshow_cpu(self):49 print('骁龙CPU')50

51 classMediaTekCPU(CPU):52 defshow_cpu(self):53 print('联发科CPU')54

55 classAppleCPU(CPU):56 defshow_cpu(self):57 print('苹果CPU')58

59 classAndroid(OS):60 defshow_os(self):61 print('Android系统')62

63 classIOS(OS):64 defshow_os(self):65 print('iOS系统')66

67 #具体工厂

68 classMiFactory(PhoneFactory):69 defmake_cpu(self):70 returnSnapDragonCPU()71

72 defmake_os(self):73 returnAndroid()74

75 defmake_shell(self):76 returnBigShell()77

78

79 classHuaweiFactory(PhoneFactory):80 defmake_cpu(self):81 returnMediaTekCPU()82

83 defmake_os(self):84 returnAndroid()85

86 defmake_shell(self):87 returnSmallShell()88

89 classIPhoneFactory(PhoneFactory):90 defmake_cpu(self):91 returnAppleCPU()92

93 defmake_os(self):94 returnIOS()95

96 defmake_shell(self):97 returnAppleShell()98

99 #客户端

100 classPhone:101 def __init__(self,cpu,os,shell):102 self.cpu=cpu103 self.os=os104 self.shell=shell105

106 defshow_info(self):107 print('手机信息:')108 self.cpu.show_cpu()109 self.os.show_os()110 self.shell.show_shell()111

112 defmake_phone(factory):113 cpu=factory.make_cpu()114 os=factory.make_os()115 shell=factory.make_shell()116 returnPhone(cpu,os,shell)117

118 pl=make_phone(IPhoneFactory())119 pl.show_info()

建造者模式

内容:将一个复杂对象的构建与它表示分离,使得同样的构建过程可以创建不同的表示。

角色:抽象建造者(Builder),具体建造者(Concrete Builder),指挥者(Director),产品(Product)

建造者模式与抽象工厂模式相似,也用来创建复杂对象。主要区别是建造者模式着重一步步构造一个复杂对象,而抽象工厂模式着重于多个系列产品对象。

适用场景:当创建复杂对象的算法(Director)应该独立于该对象的组成部分时,当构造过程允许被构造的对象有不同的表示时(不同Builder)。

优点:隐藏了一个产品的内部结构和装配过程、将构造代码与表示代码分开、可以对构造过程进行更精细的控制

例子:

1 from abc importabstractmethod,ABCMeta2 classPlayer:3 def __init__(self,face=None,body=None,arm=None,leg=None):4 self.face=face5 self.body=body6 self.arm=arm7 self.leg=leg8

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 @abstractmethod15 defbuild_face(self):16 pass

17

18 @abstractmethod19 defbuild_arm(self):20 pass

21

22 @abstractmethod23 defbuild_leg(self):24 pass

25

26 @abstractmethod27 defbuild_body(self):28 pass

29

30 @abstractmethod31 defget_player(self):32 pass

33

34 classBeautifulWomanBuilder(PlayerBuilder):35 def __init__(self):36 self.player=Player()37

38 defbuild_face(self):39 self.player.face='漂亮脸蛋'

40

41 defbuild_arm(self):42 self.player.arm='细胳膊'

43

44 defbuild_leg(self):45 self.player.leg = '长腿'

46

47 defbuild_body(self):48 self.player.body = '细腰'

49

50 defget_player(self):51 returnself.player52

53

54 classPlayDirector:55 defbuild_player(self,builder):56 builder.build_body()57 builder.build_arm()58 builder.build_leg()59 builder.build_face()60 returnbuilder.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开始,并且当设计者发现需要更大的灵活性时,设计便会向其他创建模式演化。当你在设计标准之间进行权衡的时候,了解多个模式可以给你提供更多的选择余地。

依赖于继承的创建型模式:工厂方法模式

依赖于组合的创建型模式:抽象工厂模式、创建者模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值