李建忠「设计模式」笔记

目录


设计模式目标 — 可复用

设计模式假设条件 — 存在稳定点

设计模式真谛 — 编译时复用,运行时变化。

思维方式 作用 内容
底层思维 把握机器底层微观构造 语言构造、编译转换、内存模型、运行机制
抽象思维 将现实世界抽象为程序代码 面向对象、组件封装、设计模式、架构模式

面向对象

  • 向下

    • 封装 — 隐藏内部代码

    • 继承 — 复用已有代码

    • 多态 — 改写对象行为

  • 向上

    • 深刻把握面向对象机制带来的抽象意义,理解如何利用这些机制来表达现实世界。
软件设计复杂原因

软件设计复杂性根本原因 — 变化(客户需求、技术平台、开发团队、市场)

解决复杂性
  • 分解 — 分而治之,大问题分解为多个小问题,复杂问题分解为多个简单问题(独立实现每个小类,分别实现相应的功能)

  • 抽象 — 由于不能掌握全部复杂对象,选择忽视一些非本质的细节。而去处理泛化和理想化的对象模型。(抽象一个虚基类,每个具体小类继承并重写)

C++对象模型

对象模型

几乎所有的设计模式都采用类内部组合一个对象指针的形式(指针指向多态对象以解耦合)

什么时候不用设计模式
  • 代码可读性差
  • 需求理解很浅
  • 变化尚未显现
  • 不是系统关键依赖点
  • 项目无复用价值
  • 项目将要发布
经验之谈
  • 不要为了模式而模式
  • 关注抽象类和接口
  • 理清变化点和稳定点
  • 审视依赖关系
  • 要有框架和应用的区隔思维
  • 良好的设计是演化的结果
设计模式成长之路
  1. 「手中无剑,心中无剑」 — 见模式而不知
  2. 「手中有剑,心中无剑」 — 可以识别模式,作为应用开发人员使用模式
  3. 「手中有剑,心中有剑」 — 作为框架开发人员为应用设计模式
  4. 「手中无剑,心中有剑」 — 忘掉模式,只有原则

面向对象设计原则

面向对象设计最大优势 — 抵御变化

面向对象
  • 隔离变化 — 面向对象构建方式更能适应软件变化,能将变化带来的影响降到最小(宏观)
  • 各司其职 — 需求变化导致的新增类型,不影响原来类型的实现(微观)
对象
  • 语言层面 — 对象封装了代码和数据
  • 规格层面 — 对象定义了一系列接口
  • 概念层面 — 对象是拥有某种责任的抽象
设计原则
  1. 依赖倒置原则(DIP)

    • 高层模块(稳定)不应该依赖于低层模块(变化),二者均依赖于抽象(稳定)。

    • 抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)。

  2. 开放封闭原则(OCP)

    • 对扩展开放,对更改封闭

    • 类模块应该是可扩展的,但不可修改。

  3. 单一职责原则(SRP)

    • 一个类应该仅有一个引起变化的原因
    • 变化的方向隐含类的责任
  4. Liskov替换原则(LSP)

    • 子类必须能够替换基类(子类能调用父类方法)
    • 继承表达类型抽象
  5. 接口隔离原则(ISP)

    • 不应该强迫客户程序(使用者)依赖不用的方法
    • 接口应该小而完备
  6. 优先使用对象组合,而不是类继承

    • 类继承通常为「白盒复用」,对象组合通常为「黑盒复用」
    • 继承在某种程度上破坏了封装性,耦合度高。而对象组合则要求被组合的对象具有良好定义的接口,耦合度低。
  7. 封装变化点

    • 使用封装创建对象之间的分界层,让设计者可以在其一侧修改,不会对另一侧产生不良影响。实现层次间的松耦合
  8. 针对接口编程,而非针对实现。

    • 不将变量类型声明为具体类,而是声明为接口。
    • 客户程序无需知晓对象的具体类型,只需要知道所具有的接口。

产业强盛标志 — 接口标准化

设计经验

由设计原则归纳、总结出的点

  1. 设计习语(Design Idioms) — 与特定编程语言相关的底层模式、技巧惯用法

  2. 设计模式(Design Patterns) — 类与对象之间的组织关系,包括角色、职责、协作方式

  3. 架构模式(Architectural Patterns) — 系统中与组织结构关系密切的高层模式,包括子系统划分、职责、组织关系。

设计模式分类

23个设计模式的分类原则

  • 目的

    • 创建型 — 对象创建

    • 结构型 — 对象需求变化对结构造成的冲击

    • 行为型 — 多个类交互

  • 范围

    • 类模式 — 处理类与子类的静态关系(继承)
    • 对象模式 — 对象间的动态关系(组合)
  • 封装变化

    • 组件协作 — Template Method、Strategy、Observer/Event
    • 单一职责 — Decorator、Bridge
    • 对象创建 — Factory Method、Abstract Factory、Prototype、Builder
    • 对象性能 — Singleton、Flyweight
    • 接口隔离 — Facade、Proxy、Mediator、Adapter
    • 状态变化 — Memento、State
    • 数据结构 — Composite、Iterator、Chain of Resposibility
    • 行为变化 — Command、Visitor
    • 领域问题 — Interpreter

由于时代的发展,一些设计模式已不常用:Builder、Mediator、Memento、Iterator、Chain of Resposibility、Command、Interpreter、Visitor

Refactoring to Patterns

重构获得模式是普遍认为最好的使用设计模式方法

  • 面向对象设计模式可以应对变化、提高复用。
  • 现代软件设计特征 — 需求频繁变化。
  • 设计模式的要点 — 寻找变化点(将稳定部分和变化不分分离开),变化点处使用设计模式来应对变化
  • 设计模式的应用不该先入为主(防止误用)。没有一步到位的设计模式。(故,要Refactoring to Patterns
步骤
  1. 自主增加相应的模块
  2. 思考违背哪些设计原则
  3. 重构代码
重构
  • 静态绑定 → \to 动态绑定
  • 早绑定 → \to 晚绑定
  • 继承 → \to 组合
  • 编译时依赖 → \to 运行时依赖
  • 紧耦合 → \to 松耦合

GoF23

组件协作

通过晚期绑定,实现框架与应用程序之间的松耦合。实现「框架与应用程序之间的划分」

Template Method

模板方法。定义一个操作中的算法的骨架(稳定),将一些步骤延迟(变化)到子类。使得子类可以不改变一个算法的结构(复用),同时重定义该算法的某些特定步骤。

动机

软件构造过程中,对于某项任务,有稳定的整体操作结构,但各个子步骤却有很多改变的需求;或者由于固有原因而无法和任务整体结构同时实现。

模板方法能够在稳定操作的前提下,灵活应对各个子步骤的变化及晚期实现需求。

在这里插入图片描述

  • AbstractClass — 稳定的流程
  • ConcreteClass — 实现时会变化的步骤
要点
  • Template Method是非常常用的基础设计模式,面向对象系统中大量使用。
  • Template Method机制简洁(虚函数的重载),为许多应用程序架构提供了灵活扩展点,是代码复用层面的基本实现结构。
  • Template Method内含反向控制结构(App调用Lib中的方法 → \to Lib调用App重写的方法)
  • Template Method调用的虚方法可以不做实现,但一般设计为protected方法。(流程中的一部分,不供外界调用)
样例

基类(Lib)实现执行流程,关于具体细节部分(步骤的详情),通过相应的派生类(App)去重写。

步骤的具体功能改变,不需要重写框架中的执行流程

//库
class Library{
   
public:
    //具体执行流程(定)
    void Run() {
   
        Step1();
        if(Step2()) {
   
            Step3();
        }
    }
    virtual ~Library() {
   ...}
protected:
    // 定
    void Step1() {
   ...}
    void Step3() {
   ...}
    // 变
    virtual bool 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值