【目标】通过若干典型的实验例子,介绍面向对象设计的基本原理和设计模式。通过解决问题而“获得”设计模式,以掌握设计模式的本质、揭示设计模式之间的内在联系,以期解决学习设计模式的知易行难困境。
建立面向对象设计/OOD的完整逻辑体系是一个浩大的工程,特别是以“公理化思想”为指导思想和准则的时候。
三级目录(初稿,没有正确编号的部分,需要补充完善)
第0章 基础 0.1编程语言的掌握
学习OOD的基本前提,读者首先要“熟练”地掌握一门面向对象编程语言如Java。所谓熟练,不仅对编程语言的基本语法非常熟练,而且懂得编程中基本的抽象。前者使得读者能够编写和阅读源代码;后者使得读者能够思考和理解设计的艺术/技术。
对于Java的基本语法,笔者假定读者全部知晓《编程导论(Java)》[1]介绍的内容(请参考附录2《编程导论(Java)》三级目录),包括Java泛型、反射和匿名类,本书使用到的Java8内容,将在书中补充介绍。编程的基本抽象,鉴于读者可能缺乏对这方面知识的系统理解,本节主要就基本的抽象加以概要性地说明。
0.1.1编程语言应该学习什么 0.1.2行为抽象 0.1.3数据抽象 0.1.4对象抽象简介 参考:范式 0.1.5命令编程范式 0.1.6函数编程范式 0.2 PLP详解
0.2.1一切皆概念/类型 0.2.2类层次 0.2.3抽象的力量
0.3 设计原则
设计原则(引言) 0.3.1开放封闭原则 0.3.2 高内聚与低耦合 0.3.3重构 0.4关于本书的若干说明
- 4.1 Print
- 4.2关于实验 0.4.3关于《编程导论(Java)》 0.4.4 如何学习设计模式 0.4.5关于插图 32 第1章 技术与概念 软件设计,特别是OOD领域,充满概念/术语,而且十分混乱。建立 OOD 的完整的逻辑体系,就需要梳理各种概念,澄清一些错误的认识。本章围绕回调机制展开,主要包括如下方面。
回调机制概念和两种使用场景:框架和通知。在1.1节首先介绍基本概念,并举例说明3门编程语言实现回调机制所用的技术和术语。 框架设计中面临的混乱术语,包括回调、控制反转、针对接口编程/抽象依赖原则和好莱坞法则等。 通知机制的实现。 反思和应对。 1.1 回调机制 严千钧:1.1回调机制
1.1.1框架Vs. 工具箱 1.1.2回调机制的实现 1.1.3回调函数 1.1.4 匿名类和λ表达式 1.2 框架设计者
在[1.1.1框架Vs.工具箱]中给框架一个痛快的定义:骨架式方案。因为是骨架,所以需要上层模块填充血肉——提供支持代码,之后将注意力转向到(各种语言的实现)技术。
然而,OOD领域,很多书籍和文章中会讨论到框架的所谓的特征——控制反转(Inversion of Control,IoC)。术语IoC,可以说是OOD领域概念混乱之源。本节通过另一个例子,给出框架设计的更多思考和讨论。
【实验2:框架设计者】。 实验目的:通过编写排序的测试框架,理解什么是框架、框架与库函数的区别(IoC)、理解为什么要抛弃依赖倒置原则。 实验内容:重构冒泡排序chap1.temp.BubbleSort,在此基础上编写(或者说获得)对任意排序算法进行测试的框架。 1.2.1起点 1.2.2分离与依赖 严千钧:1.2框架设计者 1.2.3 框架的复用 1.2.4 什么是控制反转(Inversion of Control,IoC) 1.2.5抛弃DIP 严千钧:1.2.5策略模式(5.9) 1.3 通知机制
1.3.1轮询VS.通知 1.3.2 观察者模式 严千钧:1.3好莱坞法则 yqj2065:1.3.3 什么是好莱坞法则 1.4 OOD领域的乱象
1.4.1 象牙塔与面包 1.4.2 更好的无绪 1.4.3 望星空 第2章 行为参数化 在软件开发中,如何应对用户频繁更改的需求是一个永恒的话题。行为参数化的意义或理论基础,就在于函数级别遵循OCP。本章介绍行为参数化相关的议题。
例解行为参数化 模板方法模式(5.10)。行为参数化的要点是,当函数中存在可变部分(需求导致的各种变化)时,可以将变化的部分抽取出来,使之变成函数的参数——行为参数。 命令模式与行为参数化 函数式编程的启发。高阶函数 Java8的通用函数接口 2.1可变的需求被参数化
严千钧:2.1可变的需求被参数化 zhuanlan.zhihu.com 图标 2.1.1为什么要将行为作为参数 2.1.2策略模式的扩展 2.1.3条件的组合 2.1.4 数据与行为的统一 2.1.5 C语言的条件组合 2.2模板方法模式(5.10) 2.2模板方法模式(5.10)
2.2.1求和函数 2.2.2 策略模式Vs. 模板方法模式 2.2.3 可变步骤如何设计 2.2.4更强的通用性) 2.3命令模式(5.2) 严千钧:4.1命令模式(Java)
4.1.1傻傻的幸福 4.1.2命令模式与行为参数化 4.1.3 适配器模式(4.1) 2.4高阶函数
2.3.1函数数据类型Vs. 函数类型签名 2.3.2柯里化 2.3.3闭包 什么是闭包[2.3.2闭包] 2.3.4延迟/惰性计算 84 2.5 Java8函数接口简介
2.4.1 Predicate 2.4.2 Function 2.4.3 Consumer 2.4.4 Supplier 第3章 创建对象 在面向对象技术中,对象的创建是一个基础性议题。既要有便捷的创建方式,也要有应对各种复杂情况的创建技巧。
按照针对接口编程/抽象依赖原则,假定Client需要依赖抽象类型IServer (后面简写为Client→IServer),除了让Client的用户传入IServer对象之外,Client如何通过“国产”方式来初始化IServer对象,使得Client依赖抽象类型IServer成为可能呢?
本章首先通过工具God,介绍针对接口编程的使能工具。之后介绍更多的使能工具,特别是Spring 的“依赖注入”模块,而该部分本质上仅仅是一个工具箱;
本章还将介绍应对各种其他场景的对象创建模式。
3.1 工具类God 3.1工具类God
3.1.1不得使用new 3.1.2抽象依赖原则的使能工具 3.1.3 更多的使能工具 3.2依赖注入容器 3.2依赖注入容器
3.2.1 Spring DI的注入方式 3.2.2 增强的God【手写IoC容器(1)、手写IoC容器(2)--容器与注入】 3.2.3 简单工厂模式3.2.4参数化工厂模式 3.2.4 什么是依赖注入* 3.3 工厂模式
严千钧:3.3工厂模式 zhuanlan.zhihu.com 图标 (3.3.1工厂方法模式(3.3)、3.3.2抽象工厂模式(3.1) )
3.4零例、单例和对象池
3.4.1零例模式 3.4.2单例模式(3.5) 3.4.3对象池 3.5装配厂模式
链式赋值模式 伪装配厂模式 真正的装配厂模式(3.2) 3.6原型模式(3.4)
模式分析 浅克隆与深克隆 克隆框架 小结 第4章 封闭型操作 4.1自引用模型
4.1.1结点 4.1.2自然数和丘奇数 严千钧:丘奇数(Church Numeral) 4.2 桥接模式(4.2)与装饰模式(4.4)
4.2.1 多次决策的嵌套/桥接 4.2.2参数化的桥接模式 4.2.3无限的装饰 4.3.1复合函数 4.3.2多项式求和* 5.2.1装饰Vs桥接 5.2.2撤销装饰 5.2.3自我装饰 4.3 数据结构型模式
5.3.1责任链模式(5.1) 164
5.3.2组合模式(4.3) 169
4.4封闭型方法
4.5 映射-归约模型
第5章 表达式问题 表达式问题(The Expression Problem或扩展性问题the extensibility problem)[1]是编程语言领域的一个根本性的两难困境。本章通过Java模拟双分派(double dispatch),自然地获得访问者模式,从而认识访问者模式的本质;然后通过解释器模式(5.3)进一步理解表达式问题。
5.1 Java模拟双分派
5.1.1分派/动态绑定 5.1.2命令和执行 5.1.3合并Shape和命令 5.1.4 Shape的行为与访问者的类型 5.2访问者模式(5.11)
5.2.1 两难的表达式问题 5.2.2对象结构 5. 3 Java的默认方法
5.3.1理想与现实 5.3.2钻石问题再现 5.4解释器模式(5.3)
5.4.1乘法解释器 5.4.2 Expr的新子类 5.4..3 Expr的新操作 第6章 迪米特法则 6.1什么是迪米特法则 236
7.1.1小函数 7.2.2迪米特法则的解读 237 6.2代理模式(4.7) 238
7.2.1从静态到动态 7.2.2代理接口 7.2.3java.lang.reflect.Proxy类源码解析 7.2.4 Java RMI 6.3 门面模式(4.5) 244
7.3.1高层接口 7.3.2如何设计门面类 案例 6.4中介模式(5.5) 248
7.4.1平台式中介 249 管家式中介 252 第7章 属性型模式 7.1 虚域模式 254
案例 256 案例 256 小结 256 7.2状态模式(5.8) 256
状态决定行为 有限状态机 案例 小结 7.3享元模式(4.6)
属性对象 外部数据 多态的属性对象 7.4备忘录模式(5.6) 268
值对象/实体模式 268
附录1 编程环境
附录2 《编程导论(Java)》三级目录
附录3 Scheme语法速查表
附录C参考书