设计模式学习笔记

198 阅读5分钟

评价代码的标准

  • 可维护性
  • 可读性
  • 可扩展性
  • 灵活性
  • 简洁性
  • 可复用性
  • 可测试性

面向对象特点

  • 封装: 信息隐藏或者数据访问保护
  • 继承:子类可以继承父类的一些特性,最大的好处是代码复用
  • 多态:子类可以替换父类,在实际的代码运行过程中,调用子类的方法实现。
    • 多台用到三个语法机制来实现
      • 要支持父类对象引用子类引用
      • 要支持继承
      • 要支持子类可以重写父类中的方法
    • 实现方式
      • duck-typing实现多态:python
      • 接口类实现多态:java
    • 作用:提高代码的可扩展性和复用性
  • 抽象:隐藏方法的具体实现,让调用者只需要关心方法提供了哪些功能,并不需要知道这些功能如何实现
  • 面向对象的优势
    • 更加能够应对大规模复杂程序的开发
    • 更易复用、易扩展、易维护
    • 编程语言更加人性化、更加高级、更加智能

抽象类和接口的区别

抽象类:可以理解为一种模板

  • 抽象类不允许被实例化,只能被继承。也就是说不能new一个抽象类对象出来
  • 抽象类可以包含属性和方法,方法既可以包含代码实现,也可以不包含代码实现(抽象方法)
  • 子类继承抽象类,必须实现抽象类中所有的抽象方法。

接口:可以理解为一种协议

  • 接口不能包含属性,只能包含抽象方法和静态常量
  • 接口只能声明方法,方法不能包含代码实现
  • 类实现接口时,必须实现接口中声明的所有方法

区别

  • 抽象类是is-a的关系,接口是has-a的关系
  • 抽象类倾向代码复用,接口倾向功能解耦

常用的设计原则

基于接口而非实现编程:Program to an interface,not an implementation

  • 基于抽象而非实现编程,在做软件开发的时候,一定要有抽象意识、封装意识、接口意识。越抽象、越顶层、越脱离魔衣具体实现的设计,越能提高代码的灵活性、扩展性、可维护性
  • 要实现基于接口而非实现编程,要做到以下三点
    • 函数命名不能暴露任何实现细节
    • 封装具体的实现细节
    • 为实现类定义抽象的接口

多用组合少用继承:

  • 为什么不用继承:继承用来表示is-a关系,倾向解决代码复用的问题。但如继承层次过深,会影响代码的可维护性。
  • 组合的优势:可以利用组合(composition)、接口、委托(delegation)三个技术手段解决继承存在的问题
  • 如何决定该用组合还是继承:如果类之间的继承结构稳定,层次比较浅,关系不复杂,可以考虑使用继承,反之可以尽量使用组合代替继承。

SOLID原则

SRP 单一职责原则:Single Responsibility Principle

一个类或模块只负责完成一个职责
a class or module shound have a single responsibility
  • 单一职责是为了实现代码高内聚、低耦合,从而提高代码的复用性、可读性、可维护性
  • 如何判断类的职责是否足够单一
    • 类中的代码行数、函数或属性过多
    • 类依赖的其他类过多,或者依赖类的其他类过多
    • 私有方法过多
    • 比较难给类起一个合适的名字
    • 类中大量的方法都是集中操作类中的某几个属性

OCP 开闭原则:对扩展开放,对修改关闭

  • 如何理解OCP
    • 添加一个新的功能,应该是通过在已有代码基础上扩展代码(新增模块、类、方法、属性等)而非修改已有代码的方式完成
    • 开闭原则并非完全杜绝修改,而是以最小的修改代码的代价完成功能的开发
    • 同样的代码改动、在粗代码粒度下肯呢个被认为是修改,在细粒度下可能被认为是扩展

LSP(Liskov Substitution Principle)里式替换原则

Functions that use pointers or references to base classes must be able to use
objects of derived classes without knowing it

ISP 接口隔离原则

  • 如何理解接口隔离原则
    • 如果理解为单个API接口或者函数,不分调用者只需要函数中的部分功能,那么就需要把函数拆分成粒度更细的多个函数,让调用者只依赖它需要的那个细粒度函数。
    • 如果理解为一组接口集合,如果部分接口只能被部分调用者使用,就需要把这部分接口隔离出来,单独给这部分调用者使用。而不强迫其他调用者也依赖这部分不会被用到的接口
    • 如果理解为OOP中的接口,设计尽量保持单一职责,不要让接口的实现类和调用者,依赖不需要的接口函数

DIP 依赖倒置原则

  • 控制反转

  • 依赖注入

  • 依赖注入框架

  • 依赖反转原则

其他

  • DRY原则

  • KISS原则(Keep it Simple and Stupid)

  • YAGNI原则

  • LOD法则

设计模式分类

创建型

  • 单例模式
  • 工厂模式
    • 工厂方法
    • 抽象工厂
  • 建造者模式
  • 原型模式

结构型

  • 代理模式
  • 桥接模式
  • 装饰着模式
  • 适配器模式
  • 门面模式
  • 组合模式
  • 享元模式

行为型

  • 观察者模式
  • 模版模式
  • 策略模式
  • 责任链模式
  • 迭代器模式
  • 状态模式
  • 访问者模式
  • 备忘录模式
  • 命令模式
  • 解释器模式
  • 中介模式