美文网首页工作生活
设计模式(十一)模板方法模式-封装算法

设计模式(十一)模板方法模式-封装算法

作者: 天色将变 | 来源:发表于2019-07-02 08:15 被阅读0次
定义

模板方法模式在一个方法中定义类一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。

解释

甲打开了一个app,买了一张汽车票,乘坐汽车,到了泰山。
乙打开了一个app,买了一张船票,乘船,到了泰山。
丙打开了一个app,买了一张机票,乘坐飞机,到了泰山。
骨架:某人,打开了一个app,买了xx,乘坐xx,到了泰山。
子类:甲乙丙提供部分算法的具体实现。

类图
image.png
伪代码
public abstract class Travel{
  public final void travel(){// 算法步骤
    openApp();
    buyTicket();
    takeVehicle();
    to();
  }
  pulbic final void openApp(){// 限定只能打开指定的app   子类不能覆盖
    System.out.println("open app");
  }
  public abstract void buyTicket();//子类实现
  public abstract void takeVehicle();//子类实现
  public final void to(){
    System.out.println("to 泰山");
  }
}
public class 甲 extends Travel{
  public void buyTicket(){ // 子类实现
    System.out.println("buy car tickey");
  }
 public void takeVehicle(){// 子类实现
    System.out.println("take car);
  }
}
public class 乙 extends Travel{
  public void buyTicket(){ // 子类实现
    System.out.println("buy ship tickey");
  }
 public void takeVehicle(){// 子类实现
    System.out.println("take ship);
  }
}

示例:

Travel travel = new 甲();
travel.travel();

travel = new 乙();
travel.travel();
描述
  • Travel就是一个算法模板,定义了一些列的算法步骤,其中部分步骤是抽象的,需要子类实现。整个Travel的算法结构是固定的。
模板方法中的钩子

钩子是一种被声明在抽象类中的方法,但只有空的或者默认的实现。钩子的存在,可以让子类有能力对算法的不同点进行挂钩。要不要挂钩,有子类自行决定。
钩子其实也是算法步骤中的一个步骤,只是有些特殊,用于控制作用。

钩子伪代码
public abstract class Travel{
  public final void travel(){// 算法步骤
    openApp();
    if(isGoodWeather()){// 好天气才出行
      buyTicket();
      takeVehicle();
      to();
    }
  }
  pulbic final void openApp(){// 限定只能打开指定的app   子类不能覆盖
    System.out.println("open app");
  }
  public abstract void buyTicket();//子类实现
  public abstract void takeVehicle();//子类实现
  public final void to(){
    System.out.println("to 泰山");
  }
  public boolean isGoodWeather(){//钩子方法,默认好天气
    return true;
  }
}
public class 甲 extends Travel{
  public void buyTicket(){ // 子类实现
    System.out.println("buy car tickey");
  }
 public void takeVehicle(){// 子类实现
    System.out.println("take car);
  }
 public void isGoodWeather(){
    return false;
  }
}
public class 乙 extends Travel{
  public void buyTicket(){ // 子类实现
    System.out.println("buy ship tickey");
  }
 public void takeVehicle(){// 子类实现
    System.out.println("take ship);
  }
}

示例:

Travel travel = new 甲();
travel.travel();// 甲的天气不好,不能出行

travel = new 乙();
travel.travel();// 乙的天气好,能出行
  • isGoodWeather()其实也是算法的一个步骤,只是超类提供类默认实现,子类选择性实现。
  • 钩子的作用是让子类有机会对模板方法中的步骤作出反应,作出一部分决定。
哪些方法需要定义为抽象方法
  • 当你的子类“必须”提供算法中某个方法或步骤的实现时,就使用抽象方法,如果算法是可选的,就用钩子。
模板方法与策略模式的却别
  • 概括来说,策略模式,使用对象组合,组合的类实现了整个算法;模板方法,使用继承,子类实现整个算法步骤中的一部分步骤细节。
  • 模板方法定义了一个算法的大纲,由子类定义其中某些步骤的内容,这么一来,在算法中的个别步骤可以有不同的实现细节,但是算法的结构依然维持不变。
  • 策略模式,定义了一个算法家族,并让这些算法可以互换。正因为每一个算法都被封装起来了,所以客户可以轻轻一地使用不同的算法。
总结
  • 模板方法定义了算法的步骤,把这些步骤的实现延迟到子类。
  • 模板方法模式为我们提供了一种代码复用的重要技巧。
  • 模板方法的抽象类可以定义具体方法、抽象方法和钩子。
  • 抽象方法由子类实现。
  • 钩子是一种方法,它在抽象类中不做事,或者只做默认的事情,子类可以选择要不要覆盖它。
  • 为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
  • 好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何以及何时调用低层模块。
  • 策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
  • 工厂方法是模板方法的一种特殊版本。

相关文章

网友评论

    本文标题:设计模式(十一)模板方法模式-封装算法

    本文链接:https://www.haomeiwen.com/subject/gsjacctx.html