尚硅谷设计模式学习(14)---[模板方法模式(Template Method Pattern)]

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了尚硅谷设计模式学习(14)---[模板方法模式(Template Method Pattern)]相关的知识,希望对你有一定的参考价值。

尚硅谷传送门==>B站尚硅谷Java设计模式

❤❤❤感谢尚硅谷❤❤❤

最近开始计划学习一下设计模式了,加油!!!



先看一个流程化 豆浆的制作问题

  • 制作豆浆的流程 选材—>添加配料—>浸泡—>放到豆浆机打碎
  • 通过添加不同的配料,可以制作出不同口味的豆浆
  • 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的

那么就得引入模板方法模式.


模板方法模式

在一个上层的抽象类定义了执行它的方法的模板。子类可按需分配 重写方法实现,但是在调用时将以抽象类中定义的方式进行。
定义一套初级模板(步骤),实现即可.

实现了最大化代码复用
适用的场景:当要完成在某个过程,该过程要执行大致相同的步骤 ,其中的部分步骤在实现时可能根据需求来处理,就考虑用模板方法设计模式

AbstractClass抽象类: 定义算法的骨架

模板方法(template) 一般 用 final 修饰,拒绝子类重写.

ConcreteClass 可添加其他实现方法,

案例解决;
关于 豆浆制作的问题,
Do soya-bean milk

在抽象类AbstractSoyBeaMilk中定义做豆浆的模板方法

public abstract class AbstractSoyBeaMilk {

    //模板方法;  做豆浆的一套模板;
    final void domark(){
        System.out.println("----开始做豆浆------");
        select();
        addBeans();
        soak();
        pulping();
        System.out.println("---ding!制作完成!!!---");
    }

    //挑选万能配料;
    void select(){
        System.out.println("步骤一:挑选配料");
    }

    //添加豆子;
    public abstract void addBeans ();

    //浸泡豆子;
    void soak(){
        System.out.println("步骤三:浸泡豆子");
    }

    //打浆水;
    void pulping (){
        System.out.println("步骤四:打浆");
    }
}

黑豆豆浆BlackSoyBeanMilk提供食材

//黑豆豆浆;
public class BlackSoyBeanMilk  extends AbstractSoyBeaMilk{
    public void addBeans() {
        System.out.println("步骤2:添加黑豆子");
    }
}

红豆豆浆RedSoyBeanMilk提供食材

//红豆豆浆
public class RedSoyBeanMilk extends AbstractSoyBeaMilk{
    public void addBeans() {
        System.out.println("步骤2:添加红豆子");
    }
}

绿豆豆浆GreenSoyBeanMilk提供食材

//绿豆豆浆;
public class GreenSoyBeanMilk extends AbstractSoyBeaMilk{
    public void addBeans() {
        System.out.println("步骤2:添加绿豆子");
    }
}

客户端Client模拟做豆浆;

//模拟客户端;
public class Client {
    public static void main(String[] args) {
        System.out.println("--------来杯绿豆豆浆------------");
        AbstractSoyBeaMilk a1=new GreenSoyBeanMilk();
        a1.domark();

        System.out.println("--------来杯黑豆豆浆------------");
        a1 = new BlackSoyBeanMilk();
        a1.domark();
    }
}
--------来杯绿豆豆浆------------
----开始做豆浆------
步骤一:挑选配料
步骤2:添加绿豆子
步骤三:浸泡豆子
步骤四:打浆
---ding!制作完成!!!---
--------来杯黑豆豆浆------------
----开始做豆浆------
步骤一:挑选配料
步骤2:添加黑豆子
步骤三:浸泡豆子
步骤四:打浆
---ding!制作完成!!!---

模板方法模式中的钩子方法

在模板方法模式的父类中,可以定义一个方法,子类可以视情况用不用重写钩子方法.

比如在刚才的豆浆制作案例中;
在抽象类AbstractSoyBeaMilk中定义一个钩子方法 `` 来决定要不要让子类去使用addBeans() 方法添加配料.

public abstract class AbstractSoyBeaMilk {

    //模板方法;  做豆浆的一套模板;
    final void domark(){
        System.out.println("----开始做豆浆------");
        select();
        //确定是否添加豆子;
        if(isAddBeans()){
            addBeans();
        }
        soak();
        pulping();
        System.out.println("---ding!制作完成!!!---");
    }


    //挑选万能配料;
    void select(){
        System.out.println("步骤一:挑选配料");
    }


    //定义钩子方法; 默认返回true;
    boolean isAddBeans() {
        return true;
    }


    //添加豆子;
    public abstract void addBeans ();

    //浸泡豆子;
    void soak(){
        System.out.println("步骤三:浸泡豆子");
    }

    //打浆水;
    void pulping (){
        System.out.println("步骤四:打浆");
    }
}

比如说,在绿豆豆浆中重写方法isAddBeans(),且给予返回值为false.

//绿豆豆浆;
public class GreenSoyBeanMilk extends AbstractSoyBeaMilk{
    public void addBeans() {
        System.out.println("步骤2:添加绿豆子");
    }

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

再次模拟

//模拟客户端;
public class Client {
    public static void main(String[] args) {
        System.out.println("--------来杯绿豆豆浆------------");
        AbstractSoyBeaMilk a1=new GreenSoyBeanMilk();
        a1.domark();
    }
}

执行时,没有第二步骤

--------来杯绿豆豆浆------------
----开始做豆浆------
步骤一:挑选配料
步骤三:浸泡豆子
步骤四:打浆
---ding!制作完成!!!---

Spring框架应用到的模板方法模式

查看接口ConfigurableApplicationContext,其中声明了一个模板方法refresh

在接口ConfigurableApplicationContext的子类AbstractApplicationContext中就有模板方法的实现;
类似于刚才的制作豆浆案例中的domark方法;

obtainFreshBeanFactory()方法
其中实现了 refreshBeanFactory 和 getBeanFactory方法

AbstractApplicationContext的子类GenericApplicationContext中实现了
refreshBeanFactory 和 getBeanFactory方法

其中的钩子方法;

postProcessBeanFactory( ) ;
onRefresh( );


以上是关于尚硅谷设计模式学习(14)---[模板方法模式(Template Method Pattern)]的主要内容,如果未能解决你的问题,请参考以下文章

尚硅谷设计模式学习(17)---[迭代器模式(Iterator Pattern)]

尚硅谷设计模式学习(21)---[解释器模式(Interpreter Pattern)]

尚硅谷设计模式学习--- [原型模式(Prototype模式),深拷贝与浅拷贝]

尚硅谷设计模式学习---[设计模式七大原则]

尚硅谷设计模式学习---[装饰者模式]

尚硅谷设计模式学习---[单例模式]