面向对象设计原则和模式

白癜风怎么预防 http://pf.39.net/bdfyy/bdfyw/180817/6466855.html

面向对象设计原则

开放封闭原则:

  一个软件实体如类、模块和函数应该对拓展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。

里氏替换原则:

  所有引用的父类的地方必须能透明的使用其子类的对象

依赖倒置原则:

  高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象;即针对接口编程,而不是针对实现编程

工厂方法模式

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

角色:

  抽象工厂角色(creator)

  具体工厂角色(concretecreator)

  抽象产品角色(product)

  具体产品角色(concreteproduct)

例子:比如我们有一个染色的机器,我们要给指定的机器生产对应的工艺编程

优点:

  每一个具体产品对应一个具体工厂类,不需要修改工厂类的代码

  隐藏了对象创建的实现细节

缺点:

  每增加一个具体的产品,就必须增加一个对应的具体工厂类

抽象工厂模式

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

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

例子:我们延续上面的染色机工艺编程的例子,一个工艺我们分为工步、参数、工步类型

fromabcimportABCMeta,abstractmethod#抽象产品classCraftParameter(metaclass=ABCMeta):#abstractclass

abstractmethoddefsetParameter(self):passclassCraftStep(metaclass=ABCMeta):#abstractclass

abstractmethoddefsetStep(self,step:list):passclassCraftFuntionType(metaclass=ABCMeta):#abstractclass

abstractmethoddefsetFuntionType(self,funcType:int):pass#抽象工厂classCreatCraftFactory(metaclass=ABCMeta):

abstractmethoddefcreatParameter(self):pass

abstractmethoddefcreatStep(self):pass

abstractmethoddefcreatFuntionType(self):pass#具体产品classModelTypeACraftParameter(CraftParameter):defsetParameter(self):print("A机型工艺的参数")classModelTypeACraftStep(CraftStep):defsetStep(self,step:list):print(f"A机型工艺的工步{step}")classModelTypeACraftFuntionType(CraftFuntionType):defsetFuntionType(self,funcType:int):print(f"A机型工艺的工步类型{funcType}")#具体工厂classModelTypeACreatCraftFactory(CreatCraftFactory):defcreatParameter(self):returnModelTypeACraftParameter()defcreatStep(self):returnModelTypeACraftStep()defcreatFuntionType(self):returnModelTypeACraftFuntionType()#客户端classCraft:def__init__(self,parameter,step,funtionType):self.parameter=parameterself.step=stepself.funtionType=funtionTypedefcraft_info(self):self.parameter.setParameter()self.step.setStep([])self.funtionType.setFuntionType(1)defcreatCraft(factory):parameter=factory.creatParameter()step=factory.creatStep()funtionType=factory.creatFuntionType()returnCraft(parameter,step,funtionType)c1=creatCraft(ModelTypeACreatCraftFactory())c1.craft_info()

优点:

  客户端与类具体实现分离

  每个工厂都有一个完成的产品系列,易于交换产品系列和产品一致性

缺点:

  难以支持新的抽象产品

单例模式

定义:保证一个类只有一个实例,并提供一个访问他的全局访问点

角色:singleton

优点:

  对唯一实例受控访问

  单例相当于全局变量,防止命名空间被污染

  常用于日志、数据库等

classSingleton:def__new__(cls,*args,**kwargs):ifnothasattr(cls,"_instance"):cls._instance=super().__new__(cls)returncls._instanceclassMyClass(Singleton):def__init__(self,a):self.a=aa=MyClass(10)b=MyClass(20)print(a.a)#20print(b.a)#20print(id(a),id(b))#id相同

适配器模式

定义:将一个类接口转换成客户希望的另一个接口。适配器使得原来接口不兼容的现在可以一起工作

类适配器:使用类的继承

对象适配器:使用组合

fromabcimportABCMeta,abstractmethodclassCraftParameter(metaclass=ABCMeta):#abstractclass

abstractmethoddefsetParameter(self):passclassModelACraftParameter(CraftParameter):defsetParameter(self):print("A机型的工艺参数")classModelBCraftParameter(CraftParameter):defsetParameter(self):print("B机型的工艺参数")classModelCCraftParameter:definsertParameter(self):print("C机型的工艺参数")#这个时候我们发现C机型方法和A、B机型的方法不一致,我们需要去适配C机型#第一种方法:类适配器classNewModelCraftParameter(CraftParameter,ModelCCraftParameter):defsetParameter(self):self.insertParameter()#第二种办法:对象适配器classCraftParameterAdapter:def__init__(self,craftParameter):self.craftParameter=craftParameterdefsetParameter(self):self.craftParameter().insertParameter()#c=NewModelCraftParameter()#c.setParameter()c=CraftParameterAdapter(ModelCCraftParameter)c.setParameter()

桥模式

角色:

  抽象

  细化抽象

  实现者

  具体实现者

场景:当事务有两个以上维度,两个维度都可以拓展

优点:

  抽象和实现分离

  具有优秀的拓展能力

fromabcimportABCMeta,abstractmethod#抽象classShape(metaclass=ABCMeta):def__init__(self,color):self.color=color

abstractmethoddefdraw(self):pass#实现者classColor(metaclass=ABCMeta):

abstractmethoddefpaint(self,shape):pass#细化抽象classTriangle(Shape):name="三角形"defdraw(self):self.color.paint(self)classCircle(Shape):name="三角形"defdraw(self):self.color.paint(self)#具体实现者classRed(Color):defpaint(self,shape):print(f"红色的{shape.name}")shape=Triangle(Red())shape.draw()

组合模式

适用于:部分--整体结构

优点:

  包含了基本对象和组合对象的类层次结构

  简化客户端代码,可以一致的使用组合对象和单个对象

  更容易增加新类型组件

fromabcimportABCMeta,abstractmethod#抽象组件classModelType(metaclass=ABCMeta):

abstractmethoddefprintModelType(self):pass#叶子组件最小的节点classSonModel(ModelType):def__init__(self,modelName):self.modelName=modelNamedef__str__(self):returnf"机型{self.modelName}"defprintModelType(self):print(self)classParentModelType(ModelType):def__init__(self,parentModelType,model):self.parentModelType=parentModelTypeself.model=modeldef__str__(self):returnf"{self.parentModelType}旗下的[{self.model}]"defprintModelType(self):print(self)#复合组件classBrand(ModelType):def__init__(self,iterable):self.sonModel=[mforminiterable]defprintModelType(self):foriinself.sonModel:i.printModelType()#p=ParentModelType("setex",SonModel("水流-02"))#p.printModelType()s1=SonModel("水流-02")p1=ParentModelType("setex",s1)b=Brand([s1,p1])b.printModelType()

外观模式

比较简单:高层代码不需要知道低层代码,只需要用封装好的就行

定义:为子系统的接口提空一个一致的界面,定义一个高层接口,这接口使得系统更容易使用

角色:

  外观

  子系统类

优点:

  减少系统依赖

  提高灵活性

  提高安全性

classLendingSinger:defstart(self):print("主唱开始唱")defstop(self):print("主唱闭嘴")classBass:defstart(self):print("贝斯开始演奏")defstop(self):print("贝斯停止演奏")classKeyboard:defstart(self):print("键盘手开始演奏")defstop(self):print("键盘手停止演奏")#更高级级别的类:乐队#通过高系统调用来封装子系统classBand:def__init__(self):self.lengdingSinger=LendingSinger()self.bass=Bass()self.keyboard=Keyboard()defstart(self):self.bass.start()self.lengdingSinger.start()self.keyboard.start()defstop(self):self.keyboard.stop()self.bass.stop()self.lengdingSinger.stop()b=Band()b.start()b.stop()

模板方法模式

定义:先写一个骨架,其中的一些细节可以延迟实现,模板方法可以使得子类不改变骨架就可以重新定义某些改变

角色:

  抽象类:定义原子操作(或者叫钩子操作),实现一个模板方法骨架

  具体类:实现原子操作

依旧拿上面的乐队作为例子

fromabcimportABCMeta,abstractmethodfromtimeimportsleepclassBand:

abstractmethoddeflengdingSinger(self):pass

abstractmethoddefbass(self):pass

abstractmethoddefkeyboard(self):#原子操作passdefrun(self):#模板方法self.bass()whileTrue:try:self.lengdingSinger()sleep(1)exceptKeyboardInterrupt:breakself.keyboard()#原子操作定义好,等后面在子类里面实现classNewBand(Band):deflengdingSinger(self):print("主唱无伴奏solo")defbass(self):print("贝斯进")defkeyboard(self):print("键盘手进")b=NewBand().run()

作者:yetangjian

出处:


转载请注明:http://www.aierlanlan.com/cyrz/1887.html