设计模式 - 模板方法模式

学习模板模式后,发现实现方式采用的就是封装、继承、抽象等Java基础知识组合而成, 这些基础我们在开发中早已熟用,只是不自知而已 ~

      • 基础概念
        • 使用场景
        • 优缺点
          • 优点
          • 缺点
        • 角色划分
          • 抽象基类
          • 具体子类
          • 场景类(使用方式)
      • Demo案例
        • 思想
        • 注意
        • 常规实现
          • 效果
          • 抽象基类 - LoveParent
          • 具体子类 - Me
          • 具体子类 - You
          • 场景类
        • 钩子实现
          • 效果
          • 抽象基类 - LoveParent
          • 具体子类 - Me
          • 具体子类 - You
          • 场景类

基础概念

主要概念是在父类(基类)中定义一个骨架、框架的流程,内部包含子类的共性方法,同时可以预留钩子方法;当然其具体的实现方式延迟在子类中执行 ~

使用场景

  • 多个子类有公有的方法,并且逻辑基本相同
  • 重要、复杂的算法, 可以把核心算法设计成模板方法, 周边的相关细节功能则由各个子类实现
  • 重构时, 模板模式是一个经常使用的模式, 把相同的代码抽取到父类中,然后通过钩子函数约束其行为

优缺点

优点
  • 封装不可变部分(便于维护) - 把不变的行为搬移到基类,去除了子类中的重复代码
  • 扩展可变部分 - 子类实现算法的某些细节,有助于算法的扩展
  • 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”
缺点
  • 子类数目的增加
  • 增加了系统实现的复杂度
  • 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍

角色划分

抽象基类
  • 基本方法
    一般均为子类的共性方法,因为使用的继承方式,所以一般都用abstract声明该方法,内部具体实现在子类中完成

  • 模板方法
    一般可以有N和N+1个具体的模板方法,同时对应着N和N+1个框架,主要实现了对基本方法调用的固有逻辑,当有N和N+1个模板方法时往往对应着不同的固有逻辑,大部分的模板方法都加上final关键字, 不允许被覆写, 以防止恶意的操作

  • 钩子方法
    此方法一般在抽象基类中已经声明,同时并非必须为抽象方法,而且在基类中的模板方法内此方法主用于判断场景导向不同的逻辑;关于具体执行哪个逻辑取决于子类是否重写执行方式(钩子就是给子类一个授权,让子类来决定模板方法的逻辑执行)

具体子类

一般均继承抽象基类,重写抽象方法,具体的实现逻辑都在对应的子类中完成

场景类(使用方式)

使用中我们一般都 new 具体子类,之后通过子类调用父类的模板方法即可 ~

Demo案例

思想

这个Demo主要针对中心思想为"感情之路",大多数人都会经历从恋爱 - 订婚 - 结婚 这样的感情过程,只要你遵循这个过程,那么就是抽象基类中的模板方法了;其中“恋爱、订婚、结婚”我们可以看做是子类的共性方法(基本方法) ,但是针对每个人喜欢什么时间去经历“恋爱、订婚、结婚”又各自不同,所以在这种场景下,我们可以使用模板模式 ~

注意

  • 因为我是做Android端的,所以文中的效果输出语句采用的Log输出 ~
  • 同因Android是基于Java的语言上进行开发的,所以针对Java开发者无影响 ~
  • 后因Android的主输出入口在onCreate生命周期,所以没必要纠结使用的场景所在 ~

常规实现

效果

设计模式 - 模板方法模式_第1张图片

抽象基类 - LoveParent
/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 抽象基类
 */
public abstract class LoveParent {

    //基本方法 - 恋爱
    public abstract void love();

    //基本方法 - 订婚
    public abstract void engagement();

    //基本方法 - 结婚
    public abstract void married();

    //模板方法 - 恋爱、订婚、结婚
    public void loveWay() {
        this.love();
        this.engagement();
        this.married();
    }
}
具体子类 - Me
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 具体子类 - Me
 */
public class Me extends LoveParent {
    @Override
    public void love() {
        Log.e("tag", "Me:我认为18岁~恋爱~最合适");
    }

    @Override
    public void engagement() {
        Log.e("tag", "Me:我认为28岁~订婚~最合适");
    }

    @Override
    public void married() {
        Log.e("tag", "Me:我认为30岁~结婚~最合适");
    }
}
具体子类 - You
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 具体子类 - You
 */
public class You extends LoveParent {
    @Override
    public void love() {
        Log.e("tag", "You:我认为20岁·恋爱·最合适");
    }

    @Override
    public void engagement() {
        Log.e("tag", "You:我认为26岁·订婚·最合适");
    }

    @Override
    public void married() {
        Log.e("tag", "You:我认为28岁·结婚·最合适");
    }
}
场景类
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Me me = new Me();
        me.loveWay();
        Log.e("tag","-------------------");
        You you = new You();
        you.loveWay();
    }
}

钩子实现

正常的流程都是 恋爱-订婚-结婚,还是不排除很多人喜欢的流程为 恋爱-结婚 ~
而实现此效果有俩种方式,一种为添加勾子方法,一种为新增一种模板方法 ~ 这里讲的是钩子方法

效果

设计模式 - 模板方法模式_第2张图片

抽象基类 - LoveParent
/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 抽象基类
 */
public abstract class LoveParent {

    //基本方法 - 恋爱
    public abstract void love();

    //基本方法 - 订婚
    public abstract void engagement();

    //基本方法 - 结婚
    public abstract void married();

    //钩子方法 - 是否必须订婚
    public boolean isHook() {
        return true;
    }

    //模板方法 - 恋爱、订婚、结婚
    public void loveWay() {
        this.love();
        if (isHook()) {
            this.engagement();
        }
        this.married();
    }
}
具体子类 - Me
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 具体子类 - Me
 */
public class Me extends LoveParent {
    public boolean hookState = true;

    public void setHook(boolean hook) {
        this.hookState = hook;
    }

    @Override
    public boolean isHook() {
        return hookState;
    }

    @Override
    public void love() {
        Log.e("tag", "Me:我认为18岁~恋爱~最合适");
    }

    @Override
    public void engagement() {
        Log.e("tag", "Me:我认为28岁~订婚~最合适");
    }

    @Override
    public void married() {
        Log.e("tag", "Me:我认为30岁~结婚~最合适");
    }
}
具体子类 - You
import android.util.Log;

/**
 * @author MrLiu
 * @date 2020/6/30
 * desc 具体子类 - You
 */
public class You extends LoveParent {
    @Override
    public void love() {
        Log.e("tag", "You:我认为20岁·恋爱·最合适");
    }

    @Override
    public void engagement() {
        Log.e("tag", "You:我认为26岁·订婚·最合适");
    }

    @Override
    public void married() {
        Log.e("tag", "You:我认为28岁·结婚·最合适");
    }
}
场景类
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Me me = new Me();
        me.setHook(false);
        me.loveWay();
        Log.e("tag","-------------------");
        You you = new You();
        you.loveWay();
    }
}

你可能感兴趣的:(设计模式)