【行为型模式】模板方法模式

一、模板方法模式概述

        模板方法模式定义在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。(类对象型模式)

  • 模板方法中的基本方法是实现算法的各个步骤,是模板方法的组成部分。基本方法又可以分为三种:
    • 抽象方法:抽象方法就是在抽象类中声明并由子类实现的方法;
    • 具体方法:具体方法可以由抽象类实现,或者由子类覆盖实现;
    • 钩子方法:钩子方法可以由抽象类实现,子类可以加以扩展。
      • 钩子方法又分为两类:
        • 第一类钩子方法是可以与一些具体步骤挂钩,以实现在不同条件下执行模板方法的不同步骤,这类方法一般返回boolean,方法名一般为isXXX();
        • 第二类钩子方法是实现体为空的具体方法,子类可以根据需要覆盖或者继承这些钩子方法
  • 模板方法模式的优缺点
    •  优点: 
      •  1.封装不变部分,扩展可变部分;
      •  2.提取公共代码,便于维护;
      •  3.行为由父类控制,子类实现。
  • 缺点:
    • 每一个不同的实现都需要一个子类来实现,导致类的个数增加,使得系统更加庞大。
  • 使用场景: 
    • 1.有多个子类共有的方法,且逻辑相同;
    • 2.重要的、复杂的方法,可以考虑作为模板方法。

注意事项为防止恶意操作,一般模板方法都加上 final 关键词。

二、代码实现

        模板方法模式有两个角色:

  • AbstractClass(抽象类):抽象类中定义了一系列基本操作,这些操作是具体的也可以是抽象的,每一个基本操作对应算法的一个步骤,在子类中可以重定义或实现这些步骤,同时抽象类实现了一个模板方法,定义一个算法的框架;
  • ConcreteClass(具体子类):实现父类中的抽象基本方法,或者覆盖父类中具体基本操作。
        2.1 抽象类
package Template.common;

public abstract class AbstractClass {
    // 模板方法定义的框架-->这就是模板方法,是final的
    public final void templateMethod() {
        /**
         * 调用基本方法,完成固定逻辑
         * 基本操作,是由子类实现的方法
         */
    	concreteOperattion();
    	primitiveOperation1();
    	primitiveOperation2();
    	if(primitiveOperation3())
            System.out.println("符合钩子方法条件");
        else
            System.out.println("不符合钩子方法条件");
    	primitiveOperation4();
        
    }
    
    // 抽象类的具体操作,共同的且繁琐的操作
    private void concreteOperattion() {
        // do something
    	System.out.println("子类一定会实现的方法concreteOperattion");
    }  
    
    public void primitiveOperation1(){
        System.out.println("抽象类具体方法primitiveOperation1");
    }
    
    // 抽象类抽象方法:由子类必须实现的操作
    protected abstract void primitiveOperation2();
    
    //第一类钩子方法
    public boolean primitiveOperation3(){
        return false;
    }

    //第二类钩子方法:默认不做事的方法,子类可以视情况决定要不要覆盖它
    public void primitiveOperation4(){

    }


}
        2.2 具体子类
package Template.common;

public class ConcreteClass1 extends AbstractClass {

	@Override
	public void primitiveOperation2(){
        System.out.println("可以不实现primitiveOperation3、primitiveOperation4,但是一定有primitiveOperation2");
    }

    public boolean primitiveOperation3(){
        return true;
        // 如果想钩子方法返回false可以不实现该方法
        // 因为父类默认返回false
        // return false;
    }

    public void primitiveOperation4(){
        System.out.println("子类覆盖父类第二类钩子方法");
    }
}
package Template.common;

public class ConcreteClass2 extends AbstractClass {
	@Override
	protected void primitiveOperation2() {
		// TODO Auto-generated method stub
		//必须继承的类
		System.out.println("可以不实现primitiveOperation3、primitiveOperation4,但是一定有primitiveOperation2");
	}

}
        2.3 main方法实现模板方法
package Template.common;

public class TemplateClient {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		AbstractClass abstractClass1 = new ConcreteClass1();
        AbstractClass abstractClass2 = new ConcreteClass2();
        System.out.println("------ConcreteClass1-------");
        applyTemplate(abstractClass1);
        System.out.println("------ConcreteClass2-------");
        applyTemplate(abstractClass2);
    }

    public static void applyTemplate(AbstractClass abstractClass){
        abstractClass.templateMethod();
    }

}
        2.4 UML图

三、代码结构图

相关推荐

  1. 设计模式(六):模板方法模式(行为模式)

    2024-04-23 01:26:04       51 阅读
  2. 设计模式行为设计模式——模板方法模式

    2024-04-23 01:26:04       37 阅读
  3. 【设计模式行为设计模式模板方法模式

    2024-04-23 01:26:04       38 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-23 01:26:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-23 01:26:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-23 01:26:04       82 阅读
  4. Python语言-面向对象

    2024-04-23 01:26:04       91 阅读

热门阅读

  1. 卸载并升级pytorch安装torcheval

    2024-04-23 01:26:04       37 阅读
  2. CV 面试指南—深度学习知识点总结(1)

    2024-04-23 01:26:04       36 阅读
  3. 前端CSS基础2(CSS基本选择器和复合选择器)

    2024-04-23 01:26:04       25 阅读
  4. 面试题

    面试题

    2024-04-23 01:26:04      36 阅读
  5. /bin/sh: 1: arm-linux-g++: not found

    2024-04-23 01:26:04       29 阅读
  6. 【Vue3源码学习】— CH3.2 VNode解析(上)

    2024-04-23 01:26:04       36 阅读
  7. leetcode 23

    2024-04-23 01:26:04       38 阅读
  8. lazarus-ide简介

    2024-04-23 01:26:04       35 阅读
  9. 安卓功耗分析

    2024-04-23 01:26:04       34 阅读
  10. Android开发——ListView

    2024-04-23 01:26:04       35 阅读
  11. mybatis和mybatis-plus的区别

    2024-04-23 01:26:04       38 阅读
  12. nginx根据二级目录转发服务以及带/和不带/的区别

    2024-04-23 01:26:04       41 阅读