设计模式:蓝图,现成的设计方案,可重用方案
《设计模式:可复用面向对象软件的基础》,23种经典面向对象设计模式
设计模式≠面向对象设计模式,但现常指代后者
底层思维:运行机制、编译转换、内存模型等
抽象思维:面向对象、设计模式、架构模式等
面向对象
向下:三大面向对象机制,封装、继承、多态
向上:抽象意义,如何表达现实世界
软件设计复杂的根本原因:变化
如客户需求、技术平台、开发团队、市场环境等
如何解决复杂性
分解:分治,抽象为小问题
抽象:忽视非本质细节,处理泛化和理想化对象模型
例子:
结构化&&抽象 实现一个 点 选中一个矩形 再放开鼠标代表选中 两种方式对比
MFC 微软基础类库
可见对Line和Rectangle分别讨论,不如将其都视为Shape,
这样如果有添加Circle的后续操作,头文件Shape.h内修改更方便
即应对变化时,提高代码的可复用性
大学生知识体系要求:中国软件工程知识体系《C-SWEBOK》
学习本课的目的:将其利用于实际生活中
面向对象设计的最大优势:抵御变化
宏观层面:隔离变化,更能适应软件变化,将影响减为最小
微观层面:各司其职,新增类不影响原有类的实现
23种具体设计模式:部分不再流行,被语言机制替代
设计原则比具体模式更重要,是使用和判别模式的关键,内化原则才能灵活使用
面向对象设计原则
(1)依赖倒置原则(DIP)
高层模块(稳定)不应该依赖于底层模块(变化),二者都应依赖于抽象(稳定)
抽象(稳定)不应该依赖于实现细节(变化),实现细节应该依赖于抽象(稳定)
如mainForm依赖于{Line,Rect,Circle},后者动态添加,故不稳定,违反依赖倒置原则
应改为mainForm和{Line,Rect,Circle}都依赖于抽象类Shape
个人理解:稳定不应该依赖于变化的
(2)开放封闭原则(OCP)
对扩展开放,对更改封闭。
类模块应该是可扩展的,但是是不可修改的。
个人理解:能在.h文件里加class,就不要在cpp里改代码重新编译
不去毁掉原来的东西,添加一些东西,满足变化带来的要求
(3)单一职责原则(SRP)
一个类应该有一个引起它变化的原因。
变化的方向隐含着类的责任。
Rectangle类里有一个area的计算面积的功能,有一个view的可视化功能。
更改这个类的一个功能势必影响到另一个功能,而这是我们不想看到的,违反了单一职责原则。
更改方法:Rectangle类内只有一个area功能,再加一个新类继承Rectangle,新类里含Draw功能
(4)Liskov替换原则(LSP)
子类必须能够替换他们的基类(IS-A)。
继承表达类型抽象。
所有用到父类的地方,都可以用子类替代。
很简单,若抽象类鸟里有Fly函数,翠鸟可以继承鸟,鸵鸟不会飞则不能继承
(5)接口隔离原则(ISP)
不应该强迫客户程序依赖他们不用的方法,接口应该小而完备。
mainForm用Shape*,也是一个接口。
个人理解:只给用户需要的,不给用户多余的,例如遥控器用不到很多功能。
例子:如果给客户提供额外的不用的接口,他们一旦使用,当更改原有必用接口,
从而导致额外的接口用不了时。本没有义务去修改,却产生了不必要的麻烦。
而口头的协商不保准的,从原则上,杜绝用到不必要或会产生麻烦串信息。