模板模式(Template)

术语

template:模板

模板模式UML类图

角色

  AbstractClass
      抽象类实现了模板方法(template),定义了算法的骨架,具体子类需要去实现 其它的抽象方法
  ConcreteClass 
      2)实现抽象方法 ,  以完成算法中特点子类的步骤

案例

需求:统计某一代码运行时间

使用前后对比

所以前:

package com.javatf.design.template.before;
  
  /**
   * @author 头发
   * @site www.javatf.com
   * @company
   * @create  2020-02-24 15:42
   */
  public class CodeTotalTime {
  
      public static void template(){
          long start = System.currentTimeMillis();
          //        检测Operation_1方法运行的时长======33
          Operation_1();
          //        检测Operation_2方法运行的时长======616
          //        Operation_2();
          long end = System.currentTimeMillis();
          System.out.println(end-start);
      }
  
      public static void Operation_1(){
  
          for (int i = 0; i<1000 ;i++){
              System.out.println("模拟耗时操作...");
          }
          System.out.print("检测Operation_1方法运行的时长======");
      }
  
      public static void Operation_2(){
  
          for (int i = 0; i<20000 ;i++){
              System.out.println("模拟耗时操作...");
          }
  
          System.out.print("检测Operation_2方法运行的时长======");
      }
  
  }
public class Client {
      public static void main(String[] args) {
          CodeTotalTime.template();
      }
  }

使用后

abstract class CodeAbstractClass {
	public void template() {
		long start = System.currentTimeMillis();
		method();
		long end = System.currentTimeMillis();
		System.out.println("当前方法执行时长:" + (end - start));
	}

	public abstract void method();
}
class ConcreteClassA extends CodeAbstractClass {
	@Override
	public void method() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("模拟耗时操作...");
		}
		System.out.print("检测ConcreteClassA.method方法运行的时长======");
	}
}
public class Client {    
	public static void main(String[] args) {
		//检测ConcreteClassA.method方法运行的时长======当前方法执行时长:
		new ConcreteClassA().template();        
		//ConcreteClassB.method方法运行的时长======当前方法执行时长:       
		new ConcreteClassB().template();    
	}
}

钩子函数应用场景: 

public abstract class CodeAbstractClass {
    public void template() {
        long start = System.currentTimeMillis();
        if (callback()) method();
        long end = System.currentTimeMillis();
        System.out.println("当前方法执行时长:" + (end - start));
    }

    public abstract void method();

    public boolean callback() {
        return true;
    }
}

从上面可以看出:template方法默认是用作统计method方法的执行时长,但是有的时候我们无需统计代码时长,template函数中有一些其它逻辑要执行,在这里我们可以考虑采用钩子函数;钩子函数被子类覆写,覆写成false,那么method方法就不会被调用,不再统计代码时长了;前端框架Vue的生命周期就有多处用到钩子函数;

 注意事项和细节
   钩子函数
    在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”
   算法只存在于一个地方,也就是在父类中,容易修改。需要修改算法时,只要修改父类的模板方法或者已经实现的某些步骤,子类就会继承这些修改
   一般模板方法都加上 **final 关键字**, 防止子类重写模板方法

 应用场景:

  Spring IOC容器加载

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模板模式和策略模式是两种常见的设计模式,它们的区别如下: 1.定义不同:模板模式定义了一个算法的骨架,将一些步骤延迟到子类中实现;策略模式定义了一系列算法,将它们封装起来,并且可以相互替换。 2.实现方式不同:模板模式使用继承来实现算法的复用;策略模式使用组合来实现算法的复用。 3.关注点不同:模板模式关注的是算法的整体流程,强调的是一致性和复用性;策略模式关注的是算法的具体实现,强调的是灵活性和可替换性。 下面是一个模板模式的例子: ```python from abc import ABC, abstractmethod class AbstractClass(ABC): def template_method(self): self.base_operation1() self.required_operation1() self.base_operation2() self.hook1() self.required_operation2() self.base_operation3() self.hook2() def base_operation1(self): print("AbstractClass says: I am doing the bulk of the work") def base_operation2(self): print("AbstractClass says: But I let subclasses override some operations") def base_operation3(self): print("AbstractClass says: But I am doing the bulk of the remaining work") @abstractmethod def required_operation1(self): pass @abstractmethod def required_operation2(self): pass def hook1(self): pass def hook2(self): pass class ConcreteClass1(AbstractClass): def required_operation1(self): print("ConcreteClass1 says: Implemented Operation1") def required_operation2(self): print("ConcreteClass1 says: Implemented Operation2") class ConcreteClass2(AbstractClass): def required_operation1(self): print("ConcreteClass2 says: Implemented Operation1") def required_operation2(self): print("ConcreteClass2 says: Implemented Operation2") def hook1(self): print("ConcreteClass2 says: Overridden Hook1") ``` 这里定义了一个抽象类AbstractClass,其中包含了一个模板方法template_method和一些基本操作base_operation1、base_operation2、base_operation3,以及一些钩子hook1、hook2。ConcreteClass1和ConcreteClass2是AbstractClass的具体子类,它们实现了抽象方法required_operation1和required_operation2,并且可以选择性地覆盖钩子方法hook1。 下面是一个策略模式的例子: ```python class Context: def __init__(self, strategy): self._strategy = strategy def do_some_business_logic(self): result = self._strategy.do_algorithm(['a', 'b', 'c', 'd', 'e']) print(','.join(result)) class Strategy: def do_algorithm(self, data): pass class ConcreteStrategyA(Strategy): def do_algorithm(self, data): return sorted(data) class ConcreteStrategyB(Strategy): def do_algorithm(self, data): return reversed(sorted(data)) context = Context(ConcreteStrategyA()) context.do_some_business_logic() context = Context(ConcreteStrategyB()) context.do_some_business_logic() ``` 这里定义了一个Context类,它接受一个Strategy对象作为参数,并且在do_some_business_logic方法中调用Strategy对象的do_algorithm方法。ConcreteStrategyA和ConcreteStrategyB是Strategy的具体子类,它们实现了do_algorithm方法,分别对数据进行排序和反转排序。 --相关问题--: 1. 什么是模板方法模式? 2. 什么是策略模式? 3. 模板模式

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值