03-行为型模式(上)

行为型模式(上)

  • 行为型模式共11种,如下所示,本文介绍前面3种:模板模式、策略模式和责任链模式。
  • 模板方法模式
  • 策略模式
  • 责任链模式
  • 观察者模式
  • 迭代子模式
  • 命令模式
  • 备忘录模式
  • 状态模式
  • 访问者模式
  • 中介者模式
  • 解释器模式

一、模板方法模式

1.1 定义

  • 父类编写算法结构代码,子类实现逻辑细节。比如一个任务需要A->B->C三个步骤,A和C步骤不会变化,变化的只有B,那么父类可以实现好AC步骤,将B留给子类自行实现。例如Thread类的run方法,子类将需要实现的细节重写在run方法。

1.2 优点和使用场景

  • 优点:简化子类开发成本,代码也比较简单,还可以屏蔽很多细节
  • 使用场景:比如JDK中的AQS,Thread类,SpringBoot中的各种数据库Template,MyBatis中的Excutor组件等。

1.3 实现

二、策略模式

2.1 定义

  • 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。 策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户端。

2.2 优点和使用场景

  • 实现面向接口编程,context依赖的是抽象的策略接口,而不是具体的策略实现类
  • 接口有多种实现的场景,并且接口需要提供给某一方使用的时候,可以考虑策略模式

2.3 实现

2.3.1 抽象策略角色
  • 通常由一个接口或抽象类实现。给出具体策略类所需的接口。
public interface Sort {

    void sort(Collection collection);
}
2.3.2 策略实现类
  • 不同的类实现具体不同的算法。
public class HeapSort implements Sort {
    @Override
    public void sort(Collection collection) {
        System.out.println("使用堆排序...");
    }
}

public class QuickSort implements Sort {
    @Override
    public void sort(Collection collection) {
        System.out.println("使用快速排序...");
    }
}
2.3.3 环境角色类
  • 持有抽象策略角色的引用,然后客户端可以由具体的方法传不同参数或实现类进去得到不同算法执行结果。
public class Context {

    Sort sort;

    public Context(Sort sort) {
        this.sort = sort;
    }

    public void contextSort(Collection collection) {
        sort.sort(collection);
    }
}
2.3.4 测试
public class StrategyTest {

    public static void main(String[] args) {
        Context context;
        if (new Random().nextBoolean()) {
            context = new Context(new QuickSort());
        } else {
            context = new Context(new HeapSort());
        }
        context.contextSort(new ArrayList());
    }
}

输出:使用堆排序和使用快速排序会交替输出
  • 策略模式的思想在于将不同类型的核心实现分开,让对客户端屏蔽具体的实现细节,可以比较方便的切换不同的算法。在JDK的集合框架中,经常需要通过构造方法传入一个比较器Comparator,或者创建比较器传入Collections的静态方法中作为方法参数,进行比较排序等,使用的是策略模式。在该比较架构中,Comparator就是一个抽象的策略;一个类实现该结构,并实现里面的compare方法,该类成为具体策略类;Collections类就是环境角色,他将集合的比较封装成静态方法对外提供api。包括在线程池中的饱和策略,线程池使用饱和策略可以理解为context,不同的饱和策略可以理解为具体的策略类,而RejectedExecutionHandler接口可以理解为策略接口。

三、责任链模式

3.1 定义

  • 把一件工作分别经过一个链上的所有节点,让所有节点依次处理任务 ,每个节点都知道后继节点是谁。

3.2 优点和使用场景

  • 优点:责任链模式将请求和处理分开,处理又可以分为很多步骤,可以提高系统的灵活性,降低耦合度。如果动态调整节点的后继,可以动态增加或者删除任务处理器,也可以很方便的增加新的处理类
  • 适用于一个工作需要多个处理类来处理的场景。

3.3 实现

  • 测试场景如下:我们有一个任务,类型可能是One,Two,Three,其他的类型不支持,然后对应三个实现类分别处理对应的任务类型,一个新任务来的时候,先又第一个类处理,处理不了就交给第二个类处理,第二个类能处理就处理,处理不了就交给下一个类处理…
3.3.1 抽象处理接口
  • 抽象处理接口定义了处理的基本方法和后继的处理对象
public interface Handler {

    void handler(String taskType);
}

public abstract class BaseHandler implements Handler {

    protected Handler nextHandler;

    public Handler getNextHandler() {
        return nextHandler;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }
}
3.3.2 具体处理类
  • 实现处理接口,实现了处理的细节并且包含具体的后继对象
public class TypeOneHandler extends BaseHandler {

    @Override
    public void handler(String taskType) {
        if ("One".equals(taskType)) {
            System.out.println("TypeOneHandler handler type one task... ");
        } else if (nextHandler != null) {
            nextHandler.handler(taskType);
        } else {
            System.out.println("TypeOneHandler can not handler task because it is not type one... ");
        }
    }
}


public class TypeTwoHandler extends BaseHandler {

    @Override
    public void handler(String taskType) {
        if ("Two".equals(taskType)) {
            System.out.println("TypeTwoHandler handler type two task... ");
        } else if (nextHandler != null) {
            nextHandler.handler(taskType);
        } else {
            System.out.println("TypeTwoHandler can not handler task because it is not type two... ");
        }
    }
}


public class TypeThreeHandler extends BaseHandler {

    @Override
    public void handler(String taskType) {
        if ("Three".equals(taskType)) {
            System.out.println("TypeThreeHandler handler type three task... ");
        } else {
            System.out.println("TypeThreeHandler can not handler task because it is not type one/two/three , abandon it ... ");
        }
    }
}
3.3.3 测试
  • 测试
public class ChainTest {

    public static void main(String[] args) {
        TypeOneHandler typeOneHandler = new TypeOneHandler();
        TypeTwoHandler typeTwoHandler = new TypeTwoHandler();
        TypeThreeHandler typeThreeHandler = new TypeThreeHandler();

        typeOneHandler.setNextHandler(typeTwoHandler);
        typeTwoHandler.setNextHandler(typeThreeHandler);

        typeOneHandler.handler("One");
        typeOneHandler.handler("Two");
        typeOneHandler.handler("Three");
        typeOneHandler.handler("Four");
    }
}
  • 输出
TypeOneHandler handler type one task... 
TypeTwoHandler handler type two task... 
TypeThreeHandler handler type three task... 
TypeThreeHandler can not handler task because it is not type one/two/three , abandon it ... 
  • 由此我们看到,责任链模式很适合有很多处理步骤的场景,而且也比较好扩展,在Javaweb中的Filter就用到了这种设计模式
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值