一.学习目标:
1.理解松耦合设计思想
2.掌握面向对象设计原则(重点)
3.掌握重构技法改善设计
4.掌握GOF核心设计模式(四人组:Gong of four)
什么是设计模式?
每一个模式描述一个在我们周围不断重复发生的问题以及该问题的解决方案的核心。
这样就能一次又一次地使用该方案而不必做重复劳动。
推荐教材:设计模式 可复用面向对象软件的基础 重点:可复用 面向对象
设计模式指的是面向对象的设计
面向对象两个思维模型:底层思维 + 抽象思维
底层思维:人和计算机沟通 向下 包括:语言构造,编译转换,内存模型,运行机制
抽象思维:将周围事物抽象成代码 向上 包括:面向对象, 组件封装, 设计模式, 架构设计
深入理解面向对象:
向下:深入理解三大面向对象机制
封装,隐藏内部实现
继承,复用现有代码
多态,改写对象行为
向上:深刻把握面向对象机制所带来的抽象意义,理解如何使用这些机制来表达显示世界,掌握什么是好的'面向对象设计'
抽象思维背景:软件设计固有的复杂性
建筑商不会在100层高楼下,突然想着修建地下室
软件设计复杂性根本原因:变化(客户需求,技术平台变化,开发团队变化, 市场变化...)
如何解决变化的复杂性:
1.分解:人们面对复杂性问题常见做法-分而治之
2.抽象:更高层次来讲,解决复杂性问题有一个通用技术,即抽象。由于不能掌握全部复杂对象,我们选择忽视它的非本质的问题
而去处理泛化和理想化了的对象模型。
关键词:抽象
结构化 vs 面向对象
软件设计的金科玉律:复用
面向对象设计最大优势:抵御变化
二:重新认识面向对象:
1.隔离变化:
从宏观层面看,面向对象的构建方式更能适应软件的变化,能将变化所带来的影响减为最小
2.各司其职:
从微观层面来看,面向对象的方式更强调各个类的'责任'
由于需求变化导致的新增类型不应该影响原来类型的实现-各负其责
3.对象是什么?
语言层面-对象封装代码+数据
规格层面-对象是一系列可悲使用的公共接口
概念层面-对象是某种拥有责任的抽象
面向对象设计原则(比某些模式具体实现更重要-可能发明更多模式或理解其他行业各种模式,
模式不能当做算法看待)(是一把尺-衡量设计模式是否正确)
1.依赖倒置原则(DIP):
高层模块(稳定)不应该依赖于底层模块(变化),二者都应该依赖于抽象(稳定)
抽象(稳定)不应该依赖于实现细节(变化), 实现细节应该依赖于抽象(稳定)
2.开放封闭原则(OCP)
对拓展开放,对更改封闭
类模块应该是可拓展的,但是不可修改的
例子:公司需要一批桌子 + 椅子 做好后加需求 需要达到防火等级 家具公司两种做法:1.做好的放弃扔掉 2.刷防火涂料(拓展修改)
3.单一职责原则(SRP)(理解不太好,在桥模式 + 装饰器模式会有更多东西)
一个类应该仅有一个引起它变化的原因 (类的成员会引起类责任的变化,成员多,多个责任使得类想不同的方向拉伸)
变化的方向隐含着类的责任
4.Liskov替换原则(LSP)
子类必须能够替换他们的基类(IS-A另外一种表达)
继承表达类型抽象
5.接口隔离原则(ISP)
不应该强迫客户程序依赖他们不用的方法
接口应该小而完备
6.优先使用对象组合而不是类继承
类继承通常为'白箱复用',对象组合通常为'黑箱复用'(标准意义上的继承并非人类子孙之间的继承,
而是类似于人继承于动物,动物继承于生物,又或者说火车继承于交通工具等)
继承在某种程度上破坏了封装性,子类父类耦合度高
对象组合则只要求被组合的对象具有良好定义的接口,耦合度低
7.封装变化点
使用封装来创建对象之间的分阶层,让设计者可以在分阶层的一侧进行修改,而不会对另一侧产生不良的影响,
从而会实现层次之间的松耦合。
8.针对接口编程而不是针对实现编程
不将变量类型声明为某个特定的具体类,而是声明为某个接口。
客户程序无需获知对象的具体类型,只需要知道对象所有的接口。
减少系统中各个部分的依赖关系,从而实现'高内聚,低耦合'的类型设计方案。
面向接口设计:接口标准化(产业强盛的标志 - 分工协作)
其他领域的智慧:
秦国为什么一统六国?
政治层面分析-有李斯,王翦等
据史书记在和考古发现,秦国的兵器无论东西南北,出图地点都有统一的标准,
包括剑,戈,弩,甚至弩机,弩体,弩头都是一样的,其他六国不是。(不一样导致运送, 分配等都出现问题)
毕昇活字印刷为什么成为四大发明,推动人类文明的前进?
毕昇之前,印刷是在木板上由工匠在其上刻字,不同的字都需要重新刻录
毕昇,定义好字的大小,木板大小,排版印刷(松耦合)
评价:毕昇是解耦合大师!
将设计原则提升为设计经验:
1.设计习语Design Idioms
Design Idioms描述与特定编程语言相关的低层模式,技巧,惯用法-effective C++等书籍描述的便是此
2.设计模式Design Patterns
Design Patterns主要描述的是'类与相互通信的对象之间的组织关系,包括他们的角色,职责,协作方式等方面'
3.架构模式 Architectural Patterns
Architectural Patterns描述系统中与基本结构组织关系密切的高层模式,
包括子系统划分,职责,以及如何组织他们之间的关系的规则。
二十三中设计模式分类:
从目的来看:
创建型(Creational)模式:将对象的部分创建工作延期到子类或者其他对象,
从而应对需求变化为对象创建时具体类型实现引来的冲击
结构型(Structural)模式:通过类继承或者对象组合获得更加灵活的结构,
从而应对需求变化为对象的结构带来的冲击
行为型(Behavioral)模式:通过类继承或者对象组合来划分类与对象间的职责,
从而应对需求变化为多个交互对象带来的冲击
从范围来看(实现手段):
类对象处理类与子类的静态关系-偏向于继承关系
对象模式处理对象间的动态关系-偏向于组合方案
从封装变化角度对模式分类:
组件协作:
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
重构获得设计模式(Refacting to Patterns):
好的面向对象设计-满足 '应对变化 提高复用'的设计
设计模式的要点是'寻找变化点', 然后在变化点处应用设计模式-变化和稳定部分离开
设计模式应用不宜先入为主-最大误用,敏捷开发提倡-重构获得设计模式(Refactoring to Patterns)
重构关键技法:
静态->动态
早绑定->迟邦定
继承->组合
编译时依赖->运行时依赖
紧耦合->松耦合