面向对象设计原则
开放封闭原则:
一个软件实体如类、模块和函数应该对拓展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
里氏替换原则:
所有引用的父类的地方必须能透明的使用其子类的对象
依赖倒置原则:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象;即针对接口编程,而不是针对实现编程
工厂方法模式
定义:创建对象的接口(工厂接口),让子类决定实例化哪一个产品类
角色:
抽象工厂角色(creator)
具体工厂角色(concretecreator)
抽象产品角色(product)
具体产品角色(concreteproduct)
例子:比如我们有一个染色的机器,我们要给指定的机器生产对应的工艺编程
优点:
每一个具体产品对应一个具体工厂类,不需要修改工厂类的代码
隐藏了对象创建的实现细节
缺点:
每增加一个具体的产品,就必须增加一个对应的具体工厂类
抽象工厂模式
定义:一个工厂类接口,让工厂子类创建一系列相关或互相依赖的对象
相比于工厂模式方法,抽象工厂模式中的每一个具体工厂都生产了一套产品
例子:我们延续上面的染色机工艺编程的例子,一个工艺我们分为工步、参数、工步类型
fromabcimportABCMeta,abstractmethod#抽象产品classCraftParameter(metaclass=ABCMeta):#abstractclass
abstractmethoddefsetParameter(self):passclassCraftStep(metaclass=ABCMeta):#abstractclassabstractmethoddefsetStep(self,step:list):passclassCraftFuntionType(metaclass=ABCMeta):#abstractclassabstractmethoddefsetFuntionType(self,funcType:int):pass#抽象工厂classCreatCraftFactory(metaclass=ABCMeta):abstractmethoddefcreatParameter(self):passabstractmethoddefcreatStep(self):passabstractmethoddefcreatFuntionType(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):passabstractmethoddefbass(self):passabstractmethoddefkeyboard(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
出处: