1.设计模式定义
每一种模式描述了一个在我们周围不断重复发生的问题以及该问题的解决方案的核心,说白了就是针对常用场景总结出来的一套编程逻辑。
2.面向对象讲起
2.1. 深入理解面向对象
1.向下
面向对象三大机制:封装-隐藏内部细节,继承-复用现有代码,多态-改写对象行为
2.向上
理解面向对象机制带来的抽象意义,即如何用这些机制表达现实世界
2.2 软件设计的复杂性
-
软件产品本身就是复杂的逻辑产品
-
复杂的根本原因就是变化:不像建筑工程,软件会随着客户需求、技术平台、开发团队等的变化而变化
-
如何解决复杂问题
(1)分解: 复杂->多个简单问题
(2)抽象:忽略复杂问题的非本质问题,而去处理泛化和理想化了的对象模型
2.3 一个实例理解分解和抽象
针对上面两种思想,举一个例子,考虑现在要实现一个画图形的程序,主体类为一个Form,在Form中有三个函数对应了画出一个图形对应的三个阶段:
onMouseDown:记录鼠标起点
onMouseUp:记录鼠标终点
onPaint:进行绘制
在onMouseUp中知道了鼠标终点后,就可以构造绘制各种图形的对象,比如直线可直接用起终点构造,长方形用起终点可得知长宽进而构造;对象构造完成之后,存入Form的数据成员中,最后进行fresh,而fresh会调用onPaint。
现在起始需求为绘制要求form可以绘制直线和矩形,那么两种思想的区别有以下几点,
1. 首先是需要绘制图形的数据结构
针对分解思想,那么就是一种类型对应一种结构
而对抽象类型来说,需要抽象出一个公共基类图形,他具备一些共有的功能:
之后根据各种图形分别实现自己的Draw方法:
2. 其次是Form中存储各种对象的数据结构:
当采用分解思想时,需要在Form中针对直线和长方形存储对应的Vector,当采用抽象思想时,存储所有绘制对象的类型为一个存储Shape*的Vector
3. 鼠标按下:记录起始点,两者没有区别
4. 鼠标抬起:两者没有太大区别,都是在得到终点后,根据起终点构造对应的图形存入之前定义的数据结构
分解思想是分别存入对应图形类型的vector;而抽象思想是存入公共基类shape*的vector中
5. 绘制:此处两者的区别就体现出来
分解思想,我们要在绘制这个主流程中,分别考虑每一个类型的图形如何绘制;
而抽象思想我们只考虑让当图形进行绘制,至于绘制的细节,在派生类中自己考虑,这样我们就可以在Form中只关注绘制这件事本身,而不用考虑如何绘制的细节;
6. 变化:现在考虑需求发生了变化,需要程序支持绘制一个圆,思考两种思想都各自需要改动什么
(1)首先基本的数据结构要支持,故分解和抽象都需要自己增加一个circle的数据结构,其中抽象需要在circle中实现draw方法
(2) Form中,分解需要增加一个针对Circle的Vector来存储绘制圆所需要的数据,而抽象不需要
(3)鼠标按下不需要修改
(4)鼠标抬起两者都需要增加针对圆形数据结构的存储(抽象后续可以通过工厂模式省略此处修改 )
(5)绘制,分解思想需要考虑圆形绘制的方法,而抽象思想不用改变,仍然考虑的是使用一个图形进行绘制,至于绘制的细节则是圆形类内部自己处理,这样可以让Form中只考虑主流程的进行,不必关注细节;
综上,当增加一个新图形的绘制需求时,分解思想基本需要在每一个步骤考虑修改,除去定义圆形这个必要的步骤,我们需要考虑在Form中如何分别存储直线、矩形、圆形;鼠标抬起时直线、矩形、圆形都是分别怎么做的;考虑绘制时如何分别绘制直线、矩形、圆形;
而抽象思想只需要在Circle的定义时考虑好实现,其他的步骤都可以省略修改,即针对不同的方法,可以统一的流程进行处理!
这说明抽象思想的 复用性 要比分解思想好很多