设计模式|模板方法

目录

 

模板方法概述

模板方法模式结构与实现

角色

策略模式的优缺点

优点

缺点

具体实现

具体方法

钩子函数


模板方法概述

模板方法的定义如下:

定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法模式是一种基于继承的代码复用技术,它是一种类行为型模式。

在程序开发中,经常会遇到这种情况:某个方法要实现的算法需要多个步骤,但其中有一些步骤是固定不变的,而另一些步骤则是不固定的。为了提高代码的可扩展性和可维护性,模板方法模式在这种场景下就派上了用场。

我们可以在父类中确定整个流程的循序,并实现固定不变的步骤,而把不固定的步骤留给子类实现。甚至可以通过一个钩子方法,让子类来决定流程中某个方法的执行与否。


模板方法模式结构与实现

è¿éåå¾çæè¿°

角色

  • AbstractClass(抽象类):在抽象类中定义了一系列基本操作(PrimitiveOperations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架,模板方法不仅可以调用在抽象类中实现的基本方法,也可以调用在抽象类的子类中实现的基本方法,还可以调用其他对象中的方法。
  • ConcreteClass(具体子类):它是抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

一个模板方法是定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。

基本方法是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种:抽象方法(Abstract Method)、具体方法(Concrete Method)和钩子方法(Hook Method)。

  • 抽象方法:一个抽象方法由抽象类声明、由其具体子类实现。
  • 具体方法:一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。
  • 钩子方法:可以与一些具体步骤 “挂钩” ,以实现在不同条件下执行模板方法中的不同步骤

策略模式的优缺点

优点

  1. 把不可改变的封装起来,把能够改变的扩展开来
  2. 他把很多类的共同操作给封装了起来,利于维护
  3. 在定义行为时候都是由父类去定义,然后子类去实现即可。

缺点

虽然把一些类的共同操作封装了起来,但是当这些类比较多时,效果就不好了,因为有一个拓展子类都需要继承它,子类多了就不好了。


具体实现

以厨师炒菜为例

具体方法

AbstractClass

public abstract class Cook {
    public abstract void oil();
    public abstract void egg();
    public abstract void tomato();
    final public void cook(){
        this.oil();
        this.egg();
        this.tomato();
    }
}

ConcreteClass

public class ChefCook extends Cook {
    @Override
    public void oil() {
        System.out.println("大厨油");
    }

    @Override
    public void egg() {
        System.out.println("大厨鸡蛋");
    }

    @Override
    public void tomato() {
        System.out.println("大厨西红柿");
    }
}
public class MeCook extends Cook{
    @Override
    public void oil() {
        System.out.println("自己油");
    }

    @Override
    public void egg() {
        System.out.println("自己鸡蛋");
    }

    @Override
    public void tomato() {
        System.out.println("自己西红柿");
    }
}

 客户端调用

public class Client {
    public static void main(String[] args) {
        Cook mycook=new MeCook();
        mycook.cook();
        ChefCook chefCook = new ChefCook();
        chefCook.cook();
    }
}

钩子函数

钩子函数决定是否执行

AbstractClass

public abstract class Cook {
    public abstract void oil();
    public abstract void egg();
    public abstract void tomato();
    //钩子方法
    public boolean isAddOil(){
        return true;
    }
    final public void cook(){
        this.egg();
        this.tomato();
        if(this.isAddOil()){
            this.oil();
        }
    }
}

ConcreteClass

public class MeCook extends Cook{
    private boolean addOilFlag=true;
    public void setIsAddOil(boolean isAddOil){
        addOilFlag=isAddOil;
    }
    @Override
    public boolean isAddOil() {
        return this.addOilFlag;
    }

    @Override
    public void oil() {
        System.out.println("自己油");
    }

    @Override
    public void egg() {
        System.out.println("自己鸡蛋");
    }

    @Override
    public void tomato() {
        System.out.println("自己西红柿");
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值