设计模式-Python

Python设计模式

1.面向对象的3大特性:

封装:将数据和方法封装到一个类里

继承:不同的类之间可以继承数据和方法

多态:python本身就是一门多态语言

2.接口:若干抽象方法的集合

接口作用:一,限制了实现接口的类必须按照给定的方式实现这些调用方法.二,对高层模块隐藏了类的内部实现原理

代码举例

#引用抽象类模块,Python实现接口的常用方法:ABC类(抽象类)
from abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta):
    @abstractmethod
    def pay(self,money):
        "pay相当于一个接口"
        #pay的作用:
        #1.拥有支付功能的接口必须写成pay定义的这样
        #2.调用pay函数时,不需要知道在不同的场景中pay的具体实现逻辑,只需要知道这个接口实现了什么功能,需要什么样的参数
        pass


class AliPay(Payment):
    "场景一:继承了Payment但是没有重写pay功能的实例化类时会报错"
    pass

class WeixPay(Payment):
    def pay(self,money):
        # 场景二:内部业务逻辑
        pass

3.面向对象设计原则:SOLID原则

开放封闭原则:程序版本迭代的过程中诸如类,模块,函数,对功能添加开放,对代码修改关闭

尽量不要在源代码的基础上修改代码,可以重新写方法来添加功能

里氏替换原则:所有引用父类的地方必须透明的使用其子类对象

父类的方法,子类若具有相同的方法,接受参数和返回结果应该和父类一致性,若不一致的话可能会导致在别处调用该方法时报错

依赖倒置原则:高层模块不应该依赖底层模块,二则都因该依赖其抽象,抽象不依赖细节,细节应该依赖于抽象

意思是程序设计时:要针对接口编程,不该针对过程编程

接口隔离原则:使用多个专门的接口,而不是用一个单一的总接口,高层代码不需要实现它不需要的代码

如:定义了一个动物类,动物有会飞的,会跑的,会游泳的,如果一个类有这三个抽象方法,假如我生成一个老虎对象,那么这个对象还要实现飞的方法,这么做显然是不合理的,合理的做法是将飞,跑,游泳分别拆分的3个动物类中,需要什么动作使用多继承就行了

单一职责原则:不要存在多于一个导致类变更的原因

一个类只负责一项职责,不要把不相干的方法揉在一起组成一个类,这些的写法虽然用了类,但不是面向对象的编程思想

4.设计模式

经典的设计模式一共是23种,通过分类可以将这23种设计模式分为3大类分别为,

创建型模式:专注于创建满足不同需求的对象

结构型模式:专注于对象之间的依赖关系,对象的结构、继承和依赖关系会影响到后续程序的维护性、代码的健壮性、耦合性

行为模式:专注于对象的具体行为

对于Python而言,有些设计模式python语言自带如迭代器,有些由于年代久远什么的反正的,对于python语言而言掌握好16种就行了

4.1创建型模式

工厂模式

工厂模式的目的是对高层代码隐藏对象创建的逻辑,也方便调用,一共有3种工厂模式

简单工厂模式

该模式不在23种设计模式中,该模式的解决方案是用一个工厂类创建所有对象,对象创建的逻辑隐藏在工厂类的方法里,但是这种这种方案违反了SOLID原则中的开放封闭原则和单一职责原则,试想一下,一个工厂类创建所有对象是不是违反单一职责原则,如果还有新的对象需要创建那么就需要改动工厂类的代码,这就违背了开放封闭原则.
抽象产品-->具体产品
工厂类-->一个工厂为所有产品服务

简单工厂模式中的角色有

工厂方法模式

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。
首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。   
工厂方法模式的对简单工厂模式进行了抽象。有一个抽象的Factory类(可以是抽象类和接口),这个类将不在负责具体的产品生产,而是只制定一些规范,具体的生产工作由其子类去完成。在这个模式中,工厂类和产品类往往可以依次对应。即一个抽象工厂对应一个抽象产品,一个具体工厂对应一个具体产品,这个具体的工厂就负责生产对应的产品。

抽象产品-->具体产品
抽象工厂-->一个工厂只为一个产品服务

简单工厂模式问题解决:
单一职责:每个工厂对应一个产品
开放封闭:增加新产品就增加新工厂类

工厂方法模式中的角色有

抽象工厂模式

抽象工厂模式是为了解决复杂对象的生产的,例如某个对象需要好多个对象组合起来才能使用,而且组合关系很复杂,高层代码需要很熟悉底层代码的逻辑才能正确调用否则容易出错,这个时候就需要抽象工厂把怎么组装这些对象的逻辑集合起来提供接口.  
比如:手机需要手机壳,CPU和操作系统,手机壳有大小,CPU有高端低端,操作系统有苹果和安卓,而且想要组成苹果手机需要苹果系统和高端CPU的,这些内部的逻辑高层代码是没不要去了解的,把逻辑封装好之后高层调用者的调用就很方便

优点:保证产品系列的完整性,易于产品系列
缺点:难以支持新的抽象产品

对于缺点的理解:新的抽象产品,比如随着市场的发展手机还需要摄像镜头,摄像镜头有不同的配置,如果是这种情况那么整体代码都需要大的改动
如果说,又添加了一种cpu型号,一种新的手机壳这些都不是新的抽象产品,这都不会影响抽象工厂

抽象工厂模式中的角色有

工厂方法模式和抽象工厂模式对比:前者生产一个产品,后者生产一套产品

建造者模式

建造者模式和抽象工厂模式差不多,也是把多个对象组装起来,这里可以对组装的过程严格把控.

还是手机组装的问题,假如这里手机的组装顺序是先装手机壳,再装CPU,再装操作系统,这里就需要把组装的功能单独拎出来只负责组装

建造者模式中的角色有

抽象建造者:

具体建造者:

指挥者:

产品:

4.2结构型模式

适配器模式

适配器使接口不兼容的类可以一起工作,使用方法可以是类的继承或则对象的组合

假如要合并两个项目,两个项目都有相似的功能,但是这两个接口的规则不一样,现在项目合并了也要把接口统一,具体做法就是
一,类适配器:一个类继承另一个类,然后在类里调用里一个类的代码
二,对象适配器:一个类接收另一个类的对象,并把对象变成自己的属性,通过属性的形式调用另一个接口

桥模式

将一个事物的两个维度分离,使其可以独立的变化

假如要画一个带颜色的图形,颜色可以有多种,图形也有多种形状

角色

抽象

细化抽象

实现者

具体实现者

组合模式

组合模式保证了多个单对象的组合模式和单个对象的使用一致性

比如:单个对象都具有的一些通用方法,这些对象组成的整体依旧具有该方法,也就是说对于对于高层代码保证了部分和整体的使用一致性

外观模式

给子系统的一组接口提供一个一致的界面,外观模式给高层代码提供了一个接口,这个接口使得这一子系统更容易使用

有点像开电脑一样,外观模式提供的就是那个开关键,子系统分别为通电,硬盘自检,进入BIOS系统,加载操作系统....一大堆,高层代码使用起来很方便,只需要按一下开机键就行了.这就有点像main函数一样,运行一下系统就启动了

代理模式

为其他对象提供一种代理,以控制对这个对象的访问,有远程代理,虚代理和保护代理

远程代理:可以隐藏对象位于远程空间的事实,如ORM
虚代理:对于某些大文件,对象创建的时候我直接生产对象,而是等需要的时候才生成
保护代理:有些对象以前没有权限,现在想加上权限可以使用保护代理

4.3行为型模式

责任链模式

使多个对象都有机会处理请求,但是要避免请求的发出者和请求的处理者直接藕和,将请求的处理者连城一条链请求一次按链传递,知道有对象处理请求为止

比如请假,把请求发给责任链的第一个人就行,如果这个对象处理不了会依次向下一个对象传递,并不是使用传统的if else 来判断

观察者模式

定义对象之间的一对多的模式,消息订阅者订阅了消息发布者之后,每当消息发布者的状态改变,消息订阅者会自动更新状态,也叫发布订阅模式

使用场景:
当一个抽象模型有两个方面,其中一个方面依赖另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用;
当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象待改变;
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧耦合的。
优点:目标和观察者之间的抽象耦合最小;支持广播通信。

策略模式

 定义一个个算法,把它们封装起来,并且使它们可以相互替换。本模式使得算法可独立于使用它的客户而变化。角色有:抽象策略、具体策略和上下文。

 优点:定义了一些列可重用的算法和行为;消除了一些条件语句;可以提供相同行为的不同实现;缺点:客户必须了解不同的策略。

模板方法模式

 内容:定义一个操作中的算法骨架,将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。使用模板方法,需要用到两种角色,分别是抽象类和具体类。抽象类的作用是是定义抽象类(钩子操作),实现一个模板方法作为算法的骨架。具体类的作用实现原子操作。

框架已经定义好了,里面的东西自己来写,Django的view视图类,中的get,post方法等和这个类似

 模板方法适用的场景:一次性实现一个算法的不变部分,各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复;控制子类扩展

posted @ 2022-07-14 09:20  Franciszw  阅读(303)  评论(0编辑  收藏  举报