模式分类
从目的看
- 创建型
- 行为型
- 结构型
    从范围看
- 类模式
- 对象模式
    新分类
- 组件协作
    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()
