设计模式之行为型模式(7种)

目录

一、模版方法模式(template )

概念

模式中的角色

模板模式UML类图

        案例

使用前

使用后

钩子函数应用场景

注意事项和细节

应用

优点

模板方法模式与开闭原则

二、命令模式

 概念:

标准UML类图

 角色

        案例

使用前

        使用后

注意事项和细节:

总结 

三、备忘录模式

概念 

        模式结构

        案例

        总结 

        四、状态模式 

概念

模式结构

 案例:

        总结

注意事项和细节 

五、责任链模式

 概念

案例

总结

六、观察者模式

概念

模式结构

案例

总结

七、策略模式 

概念

模式结构

案例

        总结


一、模版方法模式(template )

概念

模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。
比如定义一个操作中的算法的骨架,将步骤延迟到子类中。模板方法使得子类能够不去改变一个算法的结构即可重定义算法的某些特定步骤。

模式中的角色

1)AbstractClass 抽象类实现了模板方法(template),定义了算法的骨架,具体子类需要去实现 其它的抽象方法ConcreteClass

2)实现抽象方法 , 以完成算法中特点子类的步骤

模板模式UML类图

设计模式之行为型模式(7种)_第1张图片

案例

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

使用前

package com.javaxl.design.template.before;

/**
 * @author 周大福ye
 * @site www.javaxl.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方法运行的时长======");
	}
}

class ConcreteClassB extends CodeAbstractClass {
	@Override
	public void method() {
		for (int i = 0; i < 20000; i++) {
			System.out.println("模拟耗时操作...");
		}
		System.out.print("ConcreteClassB.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容器加载

        

优点

模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。

子类实现算法的某些细节,有助于算法的扩展。

通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,符合“开放-封闭原则”。

模板方法模式与开闭原则

      什么是“开闭原则”?

      开闭原则是指一个软件实体应该对扩展开放,对修

你可能感兴趣的:(设计模式,行为型,java)