设计模式 - 模板方法模式

初衷 :因架构(开发)场景(需求)而使用设计模式,莫为了使用设计模式而设计架构场景!

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

设计模式共23种,分为三种类型

  • 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式
  • 结构型模式:代理模式、装饰模式、外观模式、享元模式、桥接模式、组合模式、适配器模式
  • 行为型模式:观察者模式、策略模式、中介者模式、模版方法模式、命令模式、迭代器模式、职责链模式(责任链模式)、备忘录模式、解释器模式(Interpreter模式)、状态模式、访问者模式

基础概念

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

使用场景
  • 多个子类有公有的方法,并且逻辑基本相同
  • 重要、复杂的算法, 可以把核心算法设计成模板方法, 周边的相关细节功能则由各个子类实现
  • 重构时, 模板模式是一个经常使用的模式, 把相同的代码抽取到父类中,然后通过钩子函数约束其行为
优缺点
优点
  • 封装不可变部分(便于维护) - 把不变的行为搬移到基类,去除了子类中的重复代码
  • 扩展可变部分 - 子类实现算法的某些细节,有助于算法的扩展
  • 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”
缺点
  • 子类数目的增加
  • 增加了系统实现的复杂度
  • 继承关系自身缺点,如果父类添加新的抽象方法,所有子类都要改一遍
角色划分
抽象基类
  • 基本方法
    一般均为子类的共性方法,因为使用的继承方式,所以一般都用abstract声明该方法,内部具体实现在子类中完成

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

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

具体子类

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

场景类(使用方式)

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

Demo案例

思想

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

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

在这里插入图片描述

抽象基类 - 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();
    }
}
钩子实现

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

效果

在这里插入图片描述

抽象基类 - 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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

远方那座山

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值