模式分类
从目的看
- 创建型
- 行为型
- 结构型
从范围看
- 类模式
- 对象模式
新分类
- 组件协作
Template Method
Strategy
Observer/Event
- 单一职责
Decorator
Bridge
- 对象创建
Factory Method
Abstract Factory
Prototype
Builder
- 对象性能
Singleton
Flyweight
- 接口隔离
Facade
Proxy
Adapter
Mediator
- 状态变化
State
Memento
- 数据结构
Composite
Iterator
Chain of Responsibility
- 行为变化
Command
Visitor
- 领域问题
Interpreter
对设计模式的理解
-
对语言的补充
在语言的特性角度
-
简洁的表达类似成语
在表达上的角度
Refactoring to Patterns
- 面向对象设计模式是”好的面向对象设计”,指的是那些可以满足”应对变化,提高复用”的设计;
- 现代软件设计的特征是”需求的频繁变化”。设计模式的要点是”寻找变化点,然后在变化点处应用设计模式,从而更好的应对需求变化”,”什么时候,什么地点应用设计模式”比” 理解设计模式结构本身”更为重要;
- 设计模式的应用不宜先入为主,一上来就使用设计模式是对设计模式的最大误用。没有一步到位的设计模式。敏捷软件开发实践提倡的Refactoring to Patterns 是目前普遍公认的最好的使用设计模式的方法。
“组件协作”模式
- 现代软件专业分工之后的第一个结果是”框架与应用程序的划分”,”组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式。
- 典型模式:
Templete Method
Strategy
Observer/Event
Templete Method(模板方法)
动机 Motivation
-
在软件构建过程中,对于某一项任务,它常常有稳定的整体操作结构,但各个字步骤却有很多改变的需求,或者由于固有的原因 比如框架于应用之间的关系 而无法和任务的整体结构同时实现;
-
如何在确定稳定操作结构的前提下,来灵活应对各个字步骤的变化或晚期实现需求?
Code Example
// 程序库开发人员
public Library{
// 稳定
public void step1(){
// ...
}
// 稳定
public void step3(){
// ...
}
// 稳定
public void step5(){
// ...
}
}
// 应用开发人员
public Application{
// 变化
public boolean step2(){
// ...
return true;
}
// 变化
public void step4(){
// ...
}
// 稳定
public static void main(String args[]){
Library lib = new Library();
Application app = new Application();
// TODO: 问题在于以下算法步骤是稳定的
lib.step1();
if(app.step2()){
lib.step3();
}
for(int i = 0; i < 4; i++){
app.step4();
}
lib.step5();
}
}
Refactoring
public abstract class Library{
public void run(){ // 稳定 是谓模板方法
step1();
if(step2()){ // 支持变化,hook(多态)
step3();
}
for(int i = 0; i < 4; i++){
step4(); // 支持变化,hook(多态)
}
step5();
}
protected void step1(){ // 稳定
// ...
}
protected void step3(){ // 稳定
// ...
}
protected void step5(){ // 稳定
// ...
}
abstract boolean step2(); // 变化
abstract void step4(); // 变化
}
// 应用程序开发人员
// 做的事情变少了-> 复用
public class Application extends Library{
@Override
protected boolean step2(){
// ... 子类重写
return true;
}
@Override
protected void step4(){
// ... 子类重写
}
public static void main(String args[]){
// 多态
Library lib = new Application();
lib.run();
}
}
结构化软件设计流程
1 -> 2 -> 3 -> 4 -> 5
Library开发人员做的:
1,3,5
Application开发人员做的:
2,4
main process(主流程)
面向对象软件设计流程
1 -> 2 -> 3 -> 4 -> 5
Library开发人员做的:
1,3,5
main process
Application开发人员做的:
2,4
早绑定与晚绑定
时间先后 Library早 Application晚
- 早绑定
Application -> Library
- 晚绑定
Library -> Application
- 实现的机制
虚函数的多态调用
看GOF中对Template Method的定义
定义一个操作中的算法的骨架(稳定),而将一些步骤延迟(变化)到子类中。使得子类可以不改变(复用)一个算法的结构即可重定义(override重写)该算法的某些特定步骤。
类图
AbstractClass
- tm()
- primitiveOperation1()
- primitiveOperation2()
ConcreteClass
- primitiveOperation1()
- primitiveOperation2()
总结
- 是一种非常基础性的设计模式,在面向对象系统中有着大量的应用,用最简洁的机制(虚函数的多态性) 为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构;
- 除了可以灵活应对子步骤的变化外,”不要调用我,让我调用你”的反向控制结构也是该模式的典型应用;
- 在具体实现方面,被模板方法调用到的虚方法可以有具体实现,也可以没有,一般推荐protected修饰。
In Android
Activity
- onCreate()
- onStop()
- onDestory()
- onXxx()