设计模式之策略模式

从排序说起
在这里插入图片描述
在这里插入图片描述
如上:一个最简单的排序功能,实现了对一个int数组排序。
但现在如果是要对一个String、一个Cat类、或者一个Dog类进行排序呢?
假如要实现对猫排序,改造代码:

  • 新增一个Cat类,有weight和height两个属性

  • 新增一个CatSorter,对cat的weight进行排序
    在这里插入图片描述
    在这里插入图片描述在这里插入图片描述
    问题:

  • 假如要改成对Dog的weight排序呢?也许可以通过修改Sorter,传入一个泛型来支持对Dog的weight排序

  • 假如要改成对height进行排序呢?,那就得新增一个HeightSorter支持Height的比较,再修改Main方法的newSorter

  • 假如要对Dog的Height排序?或者又要对String排序?或者又要对Dog、Cat以后可能新增的任意属性进行排序?就算用了泛型,还是得建很多个Sorter支持对不同的属性排序,且每次都要修改main方法new出不同的sorter

再次改造
抽象出一个Comparator接口,表示比较策略的抽象,为了支持Cat\Dog\以及未来可能新增的类的比较,传入一个泛型

public interface Comparator<T> {
    int compare(T o1, T o2);
}

在sort方法中,入参传入一个比较策略的实例,调用比较策略的compare方法,进行对象的比较

public class Sorter<T> {

    public void sort(T[] arr, Comparator<T> comparator) {
        for(int i=0; i<arr.length - 1; i++) {
            int minPos = i;

            for(int j=i+1; j<arr.length; j++) {
                minPos = comparator.compare(arr[j],arr[minPos])==-1 ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }

    //sort(int)

    void swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

测试
在这里插入图片描述

  • 如果要对猫的身高进行排序,新建一个猫的身高比较策略就行
  • 如果要对狗排序,新建狗的策略 …
  • 这就是对修改关闭-对新增放开的原则——开闭原则

总结:

  • List item

延申
在实际项目中的应用
有短信发送的需求,最开始是用的A提供方的短信接口,后面又改成了B,以后还可能改成C
思路:

  • 短信发送策略接口
  • A,B,C三种不同的策略实现
  • 在业务代码的sendSMS(param,strategy)方法的入参中传入一个策略实例,方法体中调用策略实例的具体发送方法
  • 可以在配置文件中定义一个参数作为具体策略(具体策略实现的类名),在业务代码中获取此参数后通过反射获取其对象,然后以此对象作为策略参数传入sendSMS(param,strategy)
  • 如果是spring项目,在strategy实例中注入了其它的bean,那么是不能用反射来生成的(不是spring初始化的,其注入的bean将是null)。可以考虑给strategy指定beanName,交给spring来管理,获取时通过配置文件取不同的beanName,再从context中来获取对应的strategy实例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值