第六篇 编排方法 第十七章 - 模板方法模式

  方法是类的重要成员,更是对象功能的载体。接下来的两个篇目,我们将专门讨论方法的编排与驱动。
  一般来说,方法(method)描述了对象的行为,抽象方法(abstract method)声明了对象的行动目标。
  下面以植物的生长过程为例考察抽象方法的作用。

// 植物
public abstract class Plant {

  public abstract void grow();// 生长

  public abstract void bloom();// 开花

  public abstract void seed();// 结实

  public abstract void enjoy();// 享受生命

}

  这里定义了“生长”“开花”“结实”“享受生命”四个抽象方法,它们各自声明了植物的一种生命活动。虽然没有具体内容,但容易想见它们可能的动作和期望达成的目标。
  编排这些抽象方法,使它们按一定的顺序组织起来,可以得到对象的行为框架。
  来看例子。

// 植物
public abstract class Plant {

  public abstract void grow();// 生长

  public abstract void bloom();// 开花

  public abstract void seed();// 结实

  public abstract void enjoy();// 享受生命

  // 植物的生命周期(模板方法)
  public final void spendMyLife() {
    this.grow();
    this.bloom();
    this.seed();
    if (this.isItSunny()) {
      this.enjoy();
    }
  }

  // 日照充足?(钩子方法)
  public boolean isItSunny() {
    return false;
  }
}

  我们新增了 spendMyLife() 方法,它按时间顺序把植物的“生长”“开花”“结实”“享受生命”四种生命活动组织起来。从效果上来看,它描述了植物的生命周期,也就是植物如何度过自己的一生,这是植物的行为框架。
  这种组织若干抽象方法以描述对象行为框架的方法称为模板方法。模板方法被置于抽象父类中,用来约束子类对象的行为(或算法)。
  值得注意的是,这里的模板方法被 final 修饰了,这使子类无法覆写该方法,从而增强了模板方法的约束力度。与此同时,我们设置了“钩子方法”,子类可以覆写这个方法,从而在一定程度上修改父类既定的行为框架。
  冬小麦是重要的粮食作物,它的生命里有很多好听的名字。我们以此为例看看子类的样子。

// 冬小麦
public class Wheat extends Plant {

  // 生长
  public void grow() {
    // 越冬、返青、拔节
  }

  // 开花
  public void bloom() {
    // 挑旗、抽穗、扬花
  }

  // 结实
  public void seed() {
    // 灌浆、小满、成熟
  }

  // 享受生命
  public void enjoy() {
    // 麦香缕缕
  }

  // 日照充足?
  @Override
  public boolean isItSunny() {
    return true;
  }

}

// 测试类
public class Test {

  public void test() {
    Plant obj = new Wheat();
    obj.spendMyLife();
  }

}
posted on 2025-03-23 21:37  星辰河岳  阅读(26)  评论(0)    收藏  举报