Skip to content

Latest commit

 

History

History
158 lines (116 loc) · 7 KB

20230328.md

File metadata and controls

158 lines (116 loc) · 7 KB

深入设计模式

设计模式是什么?

  • 模式并不是一段特定的代码,而是解决特定问题的一般性概念

  • 算法:提供达成目标的明确步骤

  • 模式:可以看到最终的结果和模式的功能,但需要自己确定实现步骤

  • 模式的描述:

    • 意图,简单描述问题和解决方法
    • 动机,将进一步解释问题并说明模式会如何提供解决方法
    • 结构,模式每个部分和它们之间的关系
    • 在不同语言中的实现
  • 设计模式是针对软件设计中常见问题的工具箱

  • 设计模式定义了一种让团队成员能够更高效沟通的通用语言

  • 惯用技巧:最基础的、底层的模式

  • 构架模式:最通用的、高层的模式

  • 创建型模式:提供创建对象的机制

  • 结构型模式:介绍如何将对象和类组装成较大的结构

  • 行为模式:负责对象间的高效沟通和职责委派

面向对象程序设计

  • 一种范式,其理念是将数据块及数据相关的行为封装成特殊的、名为对象的实体,同时对象实体的生成工作则是基于程序员给出的一系列蓝图,这些蓝图就是类

  • 对象是类的某一个实例

  • 成员变量

  • 方法

  • 状态

  • 类的层次关系

    • 基类
    • 超类
    • 子类
  • UML:以空心箭头为顶端指向超类:继承

  • UML:普通箭头表示某个类基于另外的类

  • UML:空心三角箭头和虚线代表类实现了接口

  • UML:普通虚线箭头,表示依赖关系

  • UML:普通实线箭头表示关联关系

  • UML:空心菱形为末端指向普通实现箭头为顶端表示聚合关系

  • UML:一段为实心菱形,另一端为实线普通箭头,表示组合关系

  • 面向对象程序设计:

    • 抽象,是一种反映真实世界对象或现象中特定内容的模型,它能高精度地反映所有与特定内容相关的详细信息,同时忽略其他内容
    • 多态,抽象类,该类不提供具体实现,由子类自行提供该方法【是指程序能够检测对象所属的实际类,并在当前上下文不知道其真是类型的情况下第哦啊用其实现的能力】
    • 封装,是指一个对象对其他对象隐藏其部分状态和行为,而仅向程序其他部分暴露有限的接口的能力。interface protocol
    • 继承,根据已有类创建新类的能力
    • 依赖,是类之间最基础的、也是最微弱的关系类型【通过让代码依赖接口或者抽象类,可以降低依赖程度】
    • 关联,是一个对象使用另一个对象或另一个对象进行交互的关系【一个对象总是拥有访问与其交互的对象的权限】
    • 聚合,用于表示多个对象之间的“一对多”,“多对一”,“多对多”的关系【通常扮演容器的角色,组件可以独立于容器存在,也可以同时连接多个容器】
    • 组合,其中一个对象由一个或多个其他对象实例构成【组合与其他关系的区别在于组件仅能作为容器的一部分存在】
  • interface表示对象的公有部分

  • 接口只拥有方法

  • 一个子类只有一个父类,但可以实现多个接口

  • 依赖:对类B进行修改会影响到类A

  • 关联:对象A知道对象B,类A依赖类B

  • 聚合:对象A知道对象B,且有B构成。类A依赖与类B

  • 组合:对象A知道对象B,由B构成且管理B的声明周期

  • 实现:类A定义的方法由接口B声明,对象A可视为对象B。类A依赖于类B

  • 继承:类A继承类B的接口和实现,但是可以对其进行扩展。对象A可视为对象B。类A依赖于B

软件设计原则

优秀设计的特征

  1. 代码复用
  • 在最底层,可以复用类库、容器、容器和迭代器

  • 框架

  • 中间层【设计模式比框架更小更抽象,是对一组类的关系及其互动方式的描述】

  • 中间层的优点:在于模式提供的复用方式要比框架的风险小

  1. 扩展性
    • 变化是程序员生命中唯一不变的事情

设计原则

  1. 封装变化的内容

    • 方法层面的封装
    • 类层面的封装
  2. 面向接口进行开发,而不是面向实现

    • 依赖于抽象类型而不是具体类型

    • 示例:

      1. 确定一个对象对另一个对象的确切需求:它需要执行哪些方法?
      2. 在一个新的接口或抽象类中描述这些方法
      3. 让被依赖的类实现该接口
      4. 现在让有需求的类依赖于这个接口,而不是依赖于具体的类
    • 多态机制能帮助简化代码

  3. 组合优于继承

    • 子类不能减少超类的接口
    • 继承打破了超类的封装
    • 子类与超类紧密耦合
    • 组合是代替继承的一种方式

SOLID原则

  • 单一职责原则
  • 开闭原则:对于扩展,类应该是开放的,对于修改,类则应该是封闭的
  • 里氏替换原则
    • 子类方法的参数类型必须与其超类的参数类型相匹配或更加抽象
    • 子类方法的返回值类型必须与超类方法的返回值类型或是其子类型相匹配
    • 子类的方法不应抛出基础方法预期之外的异常类型
    • 子类不应该加强其前置条件
    • 子类不能削弱其后置条件
    • 超类的不变量必须保留
    • 子类不能修改超类中私有成员变量的值
  • 接口隔离原则,客户端不应该被强迫依赖于其不使用的方法
  • 依赖倒置原则
    • 高层次的类不应该依赖于低层次的类。二者都应该依赖于抽象接口
    • 抽象接口不应该依赖于具体实现
    • 具体实现应该依赖于抽象接口

创建型模式

  • 创建型模式提供了创建对象的机制,提高已有代码的灵活性和可复用性
  1. 工厂方法,在父类中提供一个创建对象的接口以允许子类决定实例化对象的类型
  2. 抽象工厂,能创建一系列相关的对象,而无需指定其具体类型
  3. 生成器,能够分步骤创建复杂对象。该模式允许使用相同的创建代码生成不同类型和形式的对象
  4. 原型,能够复制已有对象,而无需使代码依赖它们所属的类
  5. 单例,保证一个类只有一个实例,提供一个访问该实例的全局节点

工厂方法

  • 适用场景

    1. 当你在编写代码的过程中,无法预知对象确切类别及其依赖关系时,可使用工厂方法
    2. 如果希望用户能扩展软件库或者框架的内部组件,可使用工厂方法
    3. 如果你希望复用现有对象来节省系统资源,而不是每次都重新创建对象,可使用工厂方法
  • 优点

    1. 避免创建者和具体产品之间的紧密耦合
    2. 单一职责
    3. 开闭原则
  • 初期使用工厂方法模式,随后烟花为使用抽象工厂模式、原型模式、生成器模式

  • 抽象工厂模式通常基于一组工厂方法, 但你也可以使用原型模式来生成这些类的方法

  • 可以同时使用工厂方法和迭代器模式来让之类集合返回不同类型的迭代器

  • 原型并不是基于继承

  • 工厂方法基于继承,但不需要初始化步骤

  • 工厂方法是模板方法的一种特殊形式