跟萌新一起学设计模式(十二)之模板模式

**

设计模式(十二)之模板模式

**

  • 案例说明

      我们想要手工制作一个蛋糕,假如我们不知道制作的步骤,那就可以找个蛋糕制作的模板步骤来参考制作,我们不需要去考虑哪一步应该在什么时候做,完全按照模板的步骤照搬就行了,这就是模板模式。
    在这里插入图片描述
      Cake是一个抽象类,包含了抽象方法purchase,具体的已经实现的方法有preparemixbakingaddCream,钩子方法isPurchase,模板方法make;其子类ChocolateCakeFruitsCakeIceCreamCake分别去继承Cake,实现Cake的抽象方法purchase

      抽象的蛋糕类,模板方法make可以用final修饰。

public abstract class Cake {

    abstract void purchase();

    void prepare(){
        System.out.println("准备制作蛋糕的工具");
    }

    void mix(){
        System.out.println("搅拌鸡蛋、奶油及各种原材料");
    }

    void baking(){
        System.out.println("烘焙蛋糕");
    }

    void addCream(){
        System.out.println("加奶油装饰");
    }

    // 钩子方法
    boolean isPurchase(){
        return true;
    }

    // 模板方法
    final void make(){
        if(isPurchase()){
            purchase();
        }
        prepare();
        mix();
        baking();
        addCream();
    }
}

  具体的蛋糕子类

public class ChocolateCake extends Cake{
    @Override
    void purchase() {
        System.out.println("采购巧克力粉");
    }
}
public class FruitsCake extends Cake{
    @Override
    void purchase() {
        System.out.println("采购水果");
    }
}

  重写抽象蛋糕类中的钩子方法,假设我们已经有了冰淇淋原材料,那采购方法我们就不做任何的操作,此处体现出钩子方法的灵活性和可配置性。

public class IceCreamCake extends Cake{
    @Override
    void purchase() {

    }

    @Override
    boolean isPurchase() {
        return false;
    }
}

  客户端

public class Client {
    public static void main(String[] args) {
        Cake cake = null;
        cake = new ChocolateCake();
        // 按照模板来制作巧克力蛋糕
        cake.make();
        System.out.println("————————————————————————————————————————————————");
        cake = new FruitsCake();
        // 按照模板来制作水果蛋糕
        cake.make();
        System.out.println("————————————————————————————————————————————————");
        cake = new IceCreamCake();
        // 按照模板来制作冰淇淋蛋糕
        cake.make();
    }
}

  测试

D:\jdk8\bin\java.exe "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=56512:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath D:\jdk8\jre\lib\charsets.jar;D:\jdk8\jre\lib\deploy.jar;D:\jdk8\jre\lib\ext\access-bridge-64.jar;D:\jdk8\jre\lib\ext\cldrdata.jar;D:\jdk8\jre\lib\ext\dnsns.jar;D:\jdk8\jre\lib\ext\jaccess.jar;D:\jdk8\jre\lib\ext\jfxrt.jar;D:\jdk8\jre\lib\ext\localedata.jar;D:\jdk8\jre\lib\ext\nashorn.jar;D:\jdk8\jre\lib\ext\sunec.jar;D:\jdk8\jre\lib\ext\sunjce_provider.jar;D:\jdk8\jre\lib\ext\sunmscapi.jar;D:\jdk8\jre\lib\ext\sunpkcs11.jar;D:\jdk8\jre\lib\ext\zipfs.jar;D:\jdk8\jre\lib\javaws.jar;D:\jdk8\jre\lib\jce.jar;D:\jdk8\jre\lib\jfr.jar;D:\jdk8\jre\lib\jfxswt.jar;D:\jdk8\jre\lib\jsse.jar;D:\jdk8\jre\lib\management-agent.jar;D:\jdk8\jre\lib\plugin.jar;D:\jdk8\jre\lib\resources.jar;D:\jdk8\jre\lib\rt.jar;D:\ideaworkspace\design_pattern\design\target\classes;D:\dev_tools\repository\org\projectlombok\lombok\1.16.10\lombok-1.16.10.jar;D:\dev_tools\repository\cglib\cglib\3.3.0\cglib-3.3.0.jar;D:\dev_tools\repository\org\ow2\asm\asm\7.1\asm-7.1.jar com.wd.template.Client
采购巧克力粉
准备制作蛋糕的工具
搅拌鸡蛋、奶油及各种原材料
烘焙蛋糕
加奶油装饰
————————————————————————————————————————————————
采购水果
准备制作蛋糕的工具
搅拌鸡蛋、奶油及各种原材料
烘焙蛋糕
加奶油装饰
————————————————————————————————————————————————
准备制作蛋糕的工具
搅拌鸡蛋、奶油及各种原材料
烘焙蛋糕
加奶油装饰

Process finished with exit code 0
  • 总结

      1、算法只存在于一个地方,也就是在父类中,容易修改。需要修改算 法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改;
      2、实现了最大化代码复用。父类的模板方法和已实现的某些步骤会被子类继承而直接
    使用;
      3、既统一了算法,也提供了很大的灵活性。父类的模板方法确保了算法的结构保持不变,同时由子类提供部分步骤的实现;
      4、该模式的不足之处:每一个不同的实现都需要一个子类实现,导致类的个数增加,使得系统更加庞大;
      5、一般模板方法都加上final关键字, 防止子类重写模板方法;
      6、模板方法模式使用场景:当要完成在某个过程,该过程要执行一系列步骤 ,这一系列的步骤基本相同,但其个别步骤在实现时可能不同,通常考虑用模板方法模式来处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值