设计模式学习笔记

最近一段时间学习了设计模式方面的知识,其实有些设计模式平时工作中已经用的非常多,但不知道名字罢了,但也有些设计模式相对比较复杂难以理解。这篇博客算是对常用的设计模式进行了一些总结,不同的设计模式中蕴含着不同的设计思想,熟练掌握这些设计模式对编程水平会有很大的提高。

关于代码部分可以参考:
https://github.com/luoweifu/PyDesignPattern

创建型模式

简单工厂模式:

  • 专门定义一个类来创建其他类的实例,根据参数的不同创建不同的类实例,被创建的实例通常具有共同的父类,简单工厂模式。
  • 使用者可以不关注具体对象的类名称,只需要知道传入声明参数可以创建那些需要的对象。

工厂方法模式:

  • 抽象出一个父类Factory, 并增加多个子类分别负责创建不同的具体产品

抽象工厂模式:

  • 提供一个创建一系列或相互依赖的对象接口,而无须指定他们的具体类

单例模式:

  • 希望这个类只有一个实例
  • 项目中的一些全局管理类(Manager)可以用单例模式来实现

构建模式:

  • 将一复杂对象的构建过程和它的表现分离,使得同样的构建过程可以获取不同的表现。
  • 将产品的创建过程与产品本身分离开来,使得创建过程更加清晰,能够更加精准的控制复杂对象的创建过程。
  • 在设计构建模式中要找到并区分:产品,构建者(Builder), 指挥者(BuilderManager)
  • 当对象的创建过程比较复杂的时候,可以考虑使用构建模式,从而将对象的创建过程和对象本身的功能区分开来

原型模式

克隆模式:

  • 注意浅拷贝和深拷贝的区别,大部分情况下会用深拷贝的方式
  • 通过深拷贝的方式,可以方便创建一个具有相同属性和行为的另一个对象,特别是对于复杂对象,方便性尤为突出
  • 通过克隆的方式创建的对象,不会执行类的初始化函数

结构性模式

适配模式

  • 将一个类的接口变成客户端所期望的另一种接口,接口可以匹配。将一个对象经过包装后符合指定接口
  • 应用场景:系统需要现有的类,而这些类的接口不符合现有的系统要求
    ###组合模式
  • 将对象组合成树形结构以表示整体-部分的层次结构关系。组合使得用户对单个对象和复合对象的使用具有一致性
  • 理清部分与整体的关系,了解对象的组成结构
  • 组合UI小可以自由地增加、删除组件、可以灵活的组合不同的对象

装饰模式

  • 动态的给一个对象增加一些额外的职责,就扩展对象功能来说,装饰模式比生成子类的方式更为灵活
  • 可以增加多个装饰
  • 装饰类和被装饰类可以独立发展,不会相互耦合;装饰模式相当于继承的一个替代模式

外观模式

  • 为子系统的一组接口提供一个一致的界面为外观模式。为一个复杂的系统提供一个简单可调用额接口
  • 实现了子系统与客户端的松耦合关系
  • 在层次化结构中,可以使用外观模式定义系统中没一层的入口,层与层之间不直接产联系,而是通过外观类建立联系,降低层之间的耦合度

享元模式

  • 运用共享技术有效的支持大量细粒度对象的复用
  • 享元状态能做到共享关键是要区别内部状态和外部状态(Extrinsic State,随环境而改变,不可共享的状态), 内部状态(Instinsic State, 存储在享元对象内部不会随环境改变的状态)
  • 享元对象(Flyweight):享元对象必须是轻量级对象,也就是细粒度对象
  • 享元工厂(FlyweightFactory):负责创建和管理享元对象。享元工厂提供一个用于存储享元对象的存储池,用户需要对象时,首先从享元池中获取,
    如果不存在,就创建一个新的享元对象返回给用户,并在享元池中保存该新增对象

代理模式

  • 为其他对象提供一种代理以控制对这个对象的访问, 一个对象完成某个任务,是通过对另一个对象的引用来完成的,这种模式叫代理模式
  • 使用一个额外的间接层来支持分散可控的访问
  • 设计代理模式时,要找到并区分(真实主题:真正完成操作的具体类,代理主题:代替真实主题完成操作类)
  • 代理模式可以隐藏被代理对象的部分功能和服务,也可以增加额外功能和服务。
  • 当不想或不能直接引用一个对象是,可以考虑使用代理模式

桥接模式

  • 将抽象和实现解耦和,使得它们可以独立变化

行为型模式

职责模式

  • 为避免请求发送者和接受者耦合在一起,让每个对象都有可能接受请求。将这些接收对象连接成一条链,沿着这条链传递请求。责任链模式。
  • 确定请求者和请求内容(参数传递)
  • 确定有哪些责任人, 并对责任人进行抽象。
  • 当请求的处理具有明显的一层一层传递关系时,可以考虑使用职责模式。

命令模式

  • 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化。
  • 发送者和接受者没有任何依赖关系,只要发送订单就能完成想要完成的任务一
  • 命令模式是一种高内聚模式,把命令封装成对象,并与接收者关联在一起,从而使命令的请求者和接收者分离
  • 需要将一系列命令组合成一组操作时,可以使用宏命令的方式

解释模式

  • 描述如何使用面向对象语言构建一个简单的语言解释器(构建一门语言或者框架), 可以创建一种新的语言,这种语言拥有自己的表达式和结构。

迭代模式

  • 提供一种方法顺序的访问一组聚合对象的各个元素,而不需要暴露该对象的内部细节
  • 迭代器模式将存储数据和遍历数据分析

中介模式

  • 用一个中介对象来封装一系列对象的交互,中介者是各对象不需要显示地相互引用,从而使其耦合松散,可以独立地改变他们之间的交互

备忘模式

  • 在不破坏内部结构的前提下捕获一个对象的内部状态,这样便可以在以后恢复到原先保存的状态
  • 备忘模式的三个角色:发起人(originator, 需要进行备份的对象),备忘录(Memento, 备份的状态,一个备份的存档),备忘录管理者(Caretaker, 备份存档的管理者,交互)

监听模式

  • 明确谁是观察者,谁是被观察者
  • 在发送广播通知的时候,无须指定具体的Observer, Observer可以自己决定是否订阅Subject的通知
  • 被观察者至少需要三个方法:添加监听者,移除监听者,通知Observer. 观察者至少需要一个方法: 更新方法, 更新当前内容,做出处理
  • 应用场景:一个对象的状态或数据的更新需要其他对象的同步更新; 对象仅需要将自己的更新通知告诉给其他对象而不需要知道其他对象的细节

状态模式

  • 状态模式的核心思想是一个对象有多种状态,在不同状态下所表现出来的行为和属性不一样
  • 在实现状态模式的时候,可以把决定状态变化的属性单独抽象成一个类StateInfo, 这样判断状态属性是否符合当前状态isMatch时候就可以传入更多的信息
  • 一个操作中有大量的分支语句,且每个分支的业务逻辑都很复杂是,可以使用状态模式来拆分不同的分支逻辑,使程序有更好的可维护性

策略模式

  • 定义一系列算法,将每个算法都封装起来,并且使它们之间可以相互替换。策略模式使算法可以独立于使用它的用户而变化
  • 策略模式的三个角色。上下文环境(屏蔽上层对策略的直接访问),策略的抽象(定义统一接口,规定每个子类必须实现的方法),具体的策略
  • 如果一个系统里面有许多类,他们之间的区别仅在于有不同的行为,那么可以使用策略模式动态地让一个对象在许多行为中选择一种

模板模式

  • 定义一个操作中算法的框架,而将算法中用到了某些具体步骤放在子类实现,或者生成一个代码模板

访问模式

  • 在不改变数据结构的前提下定义作用域这些元素的新操作。将数据结构和操作解耦,方便扩展新的操作
  • 访问模式三个角色:访问者(visitor, 对数据节点进行访问和操作), 数据节点(DataNode, 要被操作的数据对象), 对象结构(数据对象的容器,可遍历容器内所有元素)
  • 访问模式将数据和算法分离,降低耦合度,增加新的访问操作也很方便
  • 访问模式将相关的访问操作集中起来定义在访问者类中,对象结构可以被不同的访问者类所使用,将对象本身与对象的访问操作分离

进阶篇

  1. 过滤器模式
  • 过滤器模式主要有三个角色:过滤的目标(要被过滤的对象,通常是一个数组), 过滤器(Filter, 负责过滤不需要的对象), 过滤器链(过滤器的集合)
  • 将对象额过滤、校验逻辑抽离出来,可以降低系统复杂度
  1. 对象池技术
  • 可以让对象重复的被使用,这就是对象池
  • 两个核心角色:对象池(对象的管理器,管理对象的借用和归还)
  1. 回调机制(callback)
  • 把函数作为参数,传递给另一个函数,延迟到另一个函数的某个时刻执行的过程叫回调
  • 在支持函数式编程的语言中,可以使用回调函数实现。作为参数传递的函数叫回调函数。在只支持面向对象的编程语言中,可以使用策略模式来实现回调机制
  1. MVC模式

你可能感兴趣的:(python)