行为型-模板模式(template)

1,模板模式简介

模板模式(模板方法模式),属于行为型设计模式。

模板模式实际上封装了一个固定流程,该流程有几个步骤组成,具体步骤细节可以由子类进行不同实现。

2,模板模式结构

1. 抽象类(模板)

抽象模板类,给出一个算法的轮廓和骨架,由一个模板方法和若干个基本方法组成。
模板方法:定义一套算法的骨架,按照某种顺序调用包含的基本方法
基本方法:算法骨架的具体实现,包含一下几种类型:
抽象方法:抽象类中声明,实例类中实现。留给子类的扩展。
具体方法:抽象类中实现,子类可以继承或者重写。
钩子方法:抽象类中实现,用于判断的逻辑方法或者需要子类重写的空方法。

2. 子类

具体实现类,实现抽象类中的抽象方法和钩子方法,一个顶级逻辑的一个组成步骤。

3,优缺点

主要优点:

  1. 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
  2. 将相同的部分代码提取到抽象父类中,可以提高代码的复用性。
  3. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

主要缺点:

  1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
  2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
  3. 由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍

4,demo

  1. 抽象类
package com.demo.base.design_partten.template;

public abstract class Animal {

    //一天生活
    final void lifeOneDay(){
        sleep();
        move();
        if(state()){
            eat();
        }
        sleep();
    }

    //具体方法
    public void eat(){
        System.out.println("any one eat by mouse!");
    }

    //抽象方法
    public abstract void move();

    public abstract void sleep();

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

  1. 子类
package com.demo.base.design_partten.template;

public class Bird extends Animal {
    @Override
    public void move() {
        System.out.println("move by wing!");
    }

    @Override
    public void sleep() {
        System.out.println("sleep on tree!");
    }
}

package com.demo.base.design_partten.template;

public class Lion extends Animal {
    @Override
    public void move() {
        System.out.println("move by legs");
    }

    @Override
    public void sleep() {
        System.out.println("sleep on the floor");
    }
}

  1. 测试类
public class Test {
    public static void main(String[] args) {
        Lion lion = new Lion();
        lion.lifeOneDay();

        Bird bird = new Bird();
        bird.lifeOneDay();
    }
}

5,使用场景

算法的整体步骤很固定,但其中个别部分易变时,这时候可以使用模板方法模式,将容易变的部分抽象出来,供子类实现。
当多个子类存在公共的行为时,可以将其提取出来并集中到一个公共父类中以避免代码重复。
当需要控制子类的扩展时,模板方法只在特定点调用钩子操作,这样就只允许在这些点进行扩展。

  1. JDK 中 AbstractList,AbstractQueuedSynchronizer
posted @ 2023-03-30 21:19  primaryC  阅读(20)  评论(0编辑  收藏  举报