面向对象设计原则和模式
面向对象设计原则
开放封闭原则:
一个软件实体如类、模块和函数应该对拓展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
里氏替换原则:
所有引用的父类的地方必须能透明的使用其子类的对象
依赖倒置原则:
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象;即针对接口编程,而不是针对实现编程
工厂方法模式
定义:创建对象的接口(工厂接口),让子类决定实例化哪一个产品类
角色:
抽象工厂角色(creator)
具体工厂角色(concrete creator)
抽象产品角色(product)
具体产品角色(concrete product)
例子:比如我们有一个染色的机器,我们要给指定的机器生产对应的工艺编程
from abc import ABCMeta, abstractmethod #抽象产品 class CraftProgramming(metaclass=ABCMeta): #abstract class @abstractmethod def setStep(self,step: list): pass #具体产品 class ModelTypeACraft(CraftProgramming): def __init__(self,childModelType=False): self.childModelType =childModelType def setStep(self,step: list): if self.childModelType: print(f"A机型-{self.childModelType}工艺工步为{step}") else: print(f"A机型工艺工步为{step}") class ModelTypeBCraft(CraftProgramming): def setStep(self,step: list): print(f"B机型工艺工步为{step}") #抽象工厂 class CraftProgrammingFactory(metaclass=ABCMeta): @abstractmethod def creatCraft(self): pass #具体工厂 class ModelTypeACraftFactory(CraftProgrammingFactory): def creatCraft(self): return ModelTypeACraft() class ModelTypeBCraftFactory(CraftProgrammingFactory): def creatCraft(self): return ModelTypeBCraft() class ModelTypeAChildCraftFactory(CraftProgrammingFactory): def creatCraft(self): return ModelTypeACraft(childModelType=True) cf = ModelTypeACraftFactory() c = cf.creatCraft() c.setStep([])
优点:
每一个具体产品对应一个具体工厂类,不需要修改工厂类的代码
隐藏了对象创建的实现细节
缺点:
每增加一个具体的产品,就必须增加一个对应的具体工厂类
抽象工厂模式
定义:一个工厂类接口,让工厂子类创建一系列相关或互相依赖的对象
相比于工厂模式方法,抽象工厂模式中的每一个具体工厂都生产了一套产品
例子:我们延续上面的染色机工艺编程的例子,一个工艺我们分为工步、参数、工步类型
from abc import ABCMeta, abstractmethod #抽象产品 class CraftParameter(metaclass=ABCMeta): #abstract class @abstractmethod def setParameter(self): pass class CraftStep(metaclass=ABCMeta): #abstract class @abstractmethod def setStep(self,step: list): pass class CraftFuntionType(metaclass=ABCMeta): #abstract class @abstractmethod def setFuntionType(self,funcType: int): pass #抽象工厂 class CreatCraftFactory(metaclass=ABCMeta): @abstractmethod def creatParameter(self): pass @abstractmethod def creatStep(self): pass @abstractmethod def creatFuntionType(self): pass #具体产品 class ModelTypeACraftParameter(CraftParameter): def setParameter(self): print("A机型工艺的参数") class ModelTypeACraftStep(CraftStep): def setStep(self,step: list): print(f"A机型工艺的工步{step}") class ModelTypeACraftFuntionType(CraftFuntionType): def setFuntionType(self,funcType: int): print(f"A机型工艺的工步类型{funcType}") #具体工厂 class ModelTypeACreatCraftFactory(CreatCraftFactory): def creatParameter(self): return ModelTypeACraftParameter() def creatStep(self): return ModelTypeACraftStep() def creatFuntionType(self): return ModelTypeACraftFuntionType() #客户端 class Craft: def __init__(self,parameter,step,funtionType): self.parameter = parameter self.step = step self.funtionType = funtionType def craft_info(self): self.parameter.setParameter() self.step.setStep([]) self.funtionType.setFuntionType(1) def creatCraft(factory): parameter = factory.creatParameter() step = factory.creatStep() funtionType = factory.creatFuntionType() return Craft(parameter,step,funtionType) c1 = creatCraft(ModelTypeACreatCraftFactory()) c1.craft_info()
优点:
客户端与类具体实现分离
每个工厂都有一个完成的产品系列,易于交换产品系列和产品一致性
缺点:
难以支持新的抽象产品
单例模式
定义:保证一个类只有一个实例,并提供一个访问他的全局访问点
角色:singleton
优点:
对唯一实例受控访问
单例相当于全局变量,防止命名空间被污染
常用于日志、数据库等
class Singleton: def __new__(cls, *args, **kwargs): if not hasattr(cls,"_instance"): cls._instance = super().__new__(cls) return cls._instance class MyClass(Singleton): def __init__(self,a): self.a = a a=MyClass(10) b=MyClass(20) print(a.a) #20 print(b.a) #20 print(id(a) , id(b)) #id相同
适配器模式
定义:将一个类接口转换成客户希望的另一个接口。适配器使得原来接口不兼容的现在可以一起工作
类适配器:使用类的继承
对象适配器:使用组合
from abc import ABCMeta, abstractmethod class CraftParameter(metaclass=ABCMeta): #abstract class @abstractmethod def setParameter(self): pass class ModelACraftParameter(CraftParameter): def setParameter(self): print("A机型的工艺参数") class ModelBCraftParameter(CraftParameter): def setParameter(self): print("B机型的工艺参数") class ModelCCraftParameter: def insertParameter(self): print("C机型的工艺参数") #这个时候我们发现C机型方法和A、B机型的方法不一致,我们需要去适配C机型 #第一种方法:类适配器 class NewModelCraftParameter(CraftParameter,ModelCCraftParameter): def setParameter(self): self.insertParameter() #第二种办法:对象适配器 class CraftParameterAdapter: def __init__(self,craftParameter): self.craftParameter = craftParameter def setParameter(self): self.craftParameter().insertParameter() # c=NewModelCraftParameter() # c.setParameter() c=CraftParameterAdapter(ModelCCraftParameter) c.setParameter()
桥模式
角色:
抽象
细化抽象
实现者
具体实现者
场景:当事务有两个以上维度,两个维度都可以拓展
优点:
抽象和实现分离
具有优秀的拓展能力
from abc import ABCMeta, abstractmethod #抽象 class Shape(metaclass=ABCMeta): def __init__(self,color): self.color = color @abstractmethod def draw(self): pass #实现者 class Color(metaclass=ABCMeta): @abstractmethod def paint(self,shape): pass #细化抽象 class Triangle(Shape): name = "三角形" def draw(self): self.color.paint(self) class Circle(Shape): name = "三角形" def draw(self): self.color.paint(self) #具体实现者 class Red(Color): def paint(self,shape): print(f"红色的{shape.name}") shape = Triangle(Red()) shape.draw()
组合模式
适用于:部分--整体结构
优点:
包含了基本对象和组合对象的类层次结构
简化客户端代码,可以一致的使用组合对象和单个对象
更容易增加新类型组件
from abc import ABCMeta, abstractmethod #抽象组件 class ModelType(metaclass=ABCMeta): @abstractmethod def printModelType(self): pass #叶子组件最小的节点 class SonModel(ModelType): def __init__(self, modelName): self.modelName = modelName def __str__(self): return f"机型{self.modelName}" def printModelType(self): print(self) class ParentModelType(ModelType): def __init__(self,parentModelType,model): self.parentModelType = parentModelType self.model = model def __str__(self): return f"{self.parentModelType}旗下的[{self.model}]" def printModelType(self): print(self) #复合组件 class Brand(ModelType): def __init__(self, iterable): self.sonModel = [m for m in iterable] def printModelType(self): for i in self.sonModel: i.printModelType() # p = ParentModelType("setex757",SonModel("水流-02")) # p.printModelType() s1 = SonModel("水流-02") p1 =ParentModelType("setex757",s1) b = Brand([s1,p1]) b.printModelType()
外观模式
比较简单:高层代码不需要知道低层代码,只需要用封装好的就行
定义:为子系统的接口提空一个一致的界面,定义一个高层接口,这接口使得系统更容易使用
角色:
外观
子系统类
优点:
减少系统依赖
提高灵活性
提高安全性
class LendingSinger: def start(self): print("主唱开始唱") def stop(self): print("主唱闭嘴") class Bass: def start(self): print("贝斯开始演奏") def stop(self): print("贝斯停止演奏") class Keyboard: def start(self): print("键盘手开始演奏") def stop(self): print("键盘手停止演奏") #更高级级别的类:乐队 #通过高系统调用来封装子系统 class Band: def __init__(self): self.lengdingSinger = LendingSinger() self.bass = Bass() self.keyboard = Keyboard() def start(self): self.bass.start() self.lengdingSinger.start() self.keyboard.start() def stop(self): self.keyboard.stop() self.bass.stop() self.lengdingSinger.stop() b=Band() b.start() b.stop()
模板方法模式
定义:先写一个骨架,其中的一些细节可以延迟实现,模板方法可以使得子类不改变骨架就可以重新定义某些改变
角色:
抽象类:定义原子操作(或者叫钩子操作),实现一个模板方法骨架
具体类:实现原子操作
依旧拿上面的乐队作为例子
from abc import ABCMeta , abstractmethod from time import sleep class Band: @abstractmethod def lengdingSinger(self): pass @abstractmethod def bass(self): pass @abstractmethod def keyboard(self):#原子操作 pass def run(self): #模板方法 self.bass() while True: try: self.lengdingSinger() sleep(1) except KeyboardInterrupt: break self.keyboard() #原子操作定义好,等后面在子类里面实现 class NewBand(Band): def lengdingSinger(self): print("主唱无伴奏solo") def bass(self): print("贝斯进") def keyboard(self): print("键盘手进") b = NewBand().run()
作者: yetangjian
出处: https://www.cnblogs.com/yetangjian/p/16449139.html
关于作者: yetangjian
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(yetangjian@outlook.com)咨询.