一:模板方法模式
1.什么是模板方法模式?
模板方法模式是一种行为设计模式, 它在超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。
模板方法的基本介绍
1.模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
2.简单说,模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤
2.模板方法模式适合应用场景
1.当你只希望客户端扩展某个特定算法步骤, 而不是整个算法或其结构时, 可使用模板方法模式。
2.当多个类的算法除一些细微不同之外几乎完全一样时, 你可使用该模式。 但其后果就是, 只要算法发生变化, 你就可能需要修改所有的类。
3.模板方法模式优缺点
优点:
1.你可仅允许客户端重写一个大型算法中的特定部分, 使得算法其他部分修改对其所造成的影响减小。
2.你可将重复代码提取到一个超类中。
缺点:
1.部分客户端可能会受到算法框架的限制
2.通过子类抑制默认步骤实现可能会导致违反里氏替换原则。
3.模板方法中的步骤越多, 其维护工作就可能会越困难。
4.模板方法模式角色:
抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。(一般是按照某种顺序执行)
基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:
1.抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。
2.具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
3.钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
一般钩子方法是用于判断的逻辑方法,这类方法名一般为isXxx,返回值类型为boolean类型。
具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级
逻辑的组成步骤。
二.模板方法代码实现
//抽象类(包含模板方法和若干个基本方法)
public abstract class AbstractClass {
//模板方法按照一定顺序执行
public final void cookProcess() {
//第一步:倒油
this.pourOil();
//第二步:热油
this.heatOil();
//第三步:倒蔬菜
this.pourVegetable();
//第四步:倒调味料
this.pourSauce();
//第五步:翻炒
this.fry();
}
//倒油步骤都一样,所以具体实现(具体方法)
public void pourOil() {
System.out.println("倒油");
}
//第二步:热油是一样的,所以直接实现(具体方法)
public void heatOil() {
System.out.println("热油");
}
//第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)钩子方法
public abstract void pourVegetable();
//第四步:倒调味料是不一样
public abstract void pourSauce();(钩子方法)
//第五步:翻炒是一样的,所以直接实现(具体方法)
public void fry(){
System.out.println("炒啊炒啊炒到熟啊");
}
}
//具体子类
public class ConcreteClass_BaoCai extends AbstractClass {
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是包菜");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是辣椒");
}
}
//具体子类
public class ConcreteClass_CaiXin extends AbstractClass {
@Override
public void pourVegetable() {
System.out.println("下锅的蔬菜是菜心");
}
@Override
public void pourSauce() {
System.out.println("下锅的酱料是蒜蓉");
}
}
//测试类
public class Client {
public static void main(String[] args) {
//炒手撕包菜
ConcreteClass_BaoCai baoCai = new ConcreteClass_BaoCai();
baoCai.cookProcess();//调用抽象类的模板方法
//炒蒜蓉菜心
ConcreteClass_CaiXin caiXin = new ConcreteClass_CaiXin();
caiXin.cookProcess();//调用抽象类的模板方法
}
}