策略模式

策略模式

场景:

当我们有猫这个对象时,需要根据猫的属性进行排序(比如根据体重排序)

  • 猫有两个属性 身高 提供
  • implements Comparable 实现一个比较方法
  • 代码实现根据体重进行排序 comparateTo(Cat a)
public class Cat implements Comparable<Cat> {

    private Integer weight;

    private Integer height;

    @Override
    public String toString() {
        return "Cat{" +
                "weight=" + weight +
                ", height=" + height +
                '}';
    }

    public Cat(Integer weight, Integer height) {
        this.weight = weight;
        this.height = height;
    }


    public Integer getWeight() {
        return weight;
    }

    public Integer getHeight() {
        return height;
    }


    /**
     * 根据体重进行排序
     * @param a
     * @return
     */
    @Override
    public Integer comparateTo(Cat a) {

        if (a.getWeight() > this.weight) return 1;
        else if (a.getWeight() < this.weight) return -1;
        return 0;
    }
}
public interface Comparable<T> {
    /**
     * 比较方法
     * @param t
     * @return
     */
    Integer comparateTo(T t);
}

让我们来给他们排序

  • 使用简单的选择排序(拿一个值遍历所有的值排序)
  • 根据实现 Comparable 对象的方法来进行排序(上面猫实现的是根据体重排序)
public class SortHandler{


    public static void sort(Comparable[] arr){

        for (int i = 0; i < arr.length-1; i++) {
            int num = i;

            for (int j = i+1; j < arr.length; j++) {
                //根据传入对象的实现方法进行排序
               num = arr[i].comparateTo(arr[j])>0?j:i;
            }

            //位置转换
            swap(arr,i,num);
        }
    }

    public static void swap(Comparable[] arr,Integer i ,Integer j){

        Comparable com = arr[j];

        arr[j] = arr[i];

        arr[i] = com;
    }
}
  • 这是测试方法
  • 创建三只猫 根据体重进行排序
public static void main(String[] args) {

        Comparable[] arr = {new Cat(4,4),new Cat(1,1),new Cat(5,5)};

        SortHandler.sort(arr);

        System.out.println(Arrays.toString(arr));
    }
万恶的产品来了,提要求让我们改成根据猫的身高来进行排序,这时可以:
  • 改猫的代码.修改猫实现的 comparateTo 方法,改为根据身高排序

  • 但是这样违背了设计模式的开闭原则

  • 产品变更的内容只能是排序方面的,所以我们根据排序规则,需要优化一下代码

  • 先指定一个规则接口

public interface Comparator<T> {


    /**
     * 比较对象
     * @param t1
     * @param t2
     * @return
     */
    Integer comparatorTo(T t1,T t2);
}
  • 定义猫根据身高进行排序的规则
  • 比较传入两只猫的身高,返回是否
public class CarHeightComparator implements Comparator<Cat>{


    @Override
    public Integer comparatorTo(Cat t1, Cat t2) {

        if(t1.getHeight()>t2.getHeight()) return 1;
        else if(t1.getHeight()<t2.getHeight()) return -1;
        return 0;
    }
}
  • 定义一个通过排序接口实现类
  • 入参: 比较对象集合 比较方法(根据身高/提供)
public class SortComparatorHandler<T>{


    public void sort(T[] arr,Comparator<T> comparator){

        for (int i = 0; i < arr.length-1; i++) {
            int num = i;

            for (int j = i+1; j < arr.length; j++) {

               num = comparator.comparatorTo(arr[i],arr[j]) == -1?j:i;
            }

            //位置转换
            swap(arr,i,num);
        }
    }

    public void swap(T[] arr,Integer i ,Integer j){

        T com = arr[j];

        arr[j] = arr[i];

        arr[i] = com;
    }
}
  • 测试方法
 public static void main(String[] args) {
       //通过策略模式 根据比较器的实现方法来进行比较
        SortComparatorHandler sort = new SortComparatorHandler();
        sort.sort(arr,new CarHeightComparator());
        System.out.println(Arrays.toString(arr));
    }
如果这样写的话,产品在需要改需求,我们不需要修改原代码,只需要重新提供一个根据新的排序规则方法的实现类,替换原先的排序规则就可以了
  • 使用java8写法 一个方法里面只有一个方法,直接这么写
  • SortComparatorHandler 这个方法里面的入参都要定义泛型(两个都要)
public static void main(String[] args) {

        Cat[] arr = {new Cat(4,4),new Cat(1,1),new Cat(5,5)};

        //通过策略模式 根据比较器的实现方法来进行比较
        SortComparatorHandler<Cat> sort = new SortComparatorHandler<>();
        sort.sort(arr, (t1,t2)->{
            if(t1.getHeight()>t2.getHeight()) return 1;
            else if(t1.getHeight()<t2.getHeight()) return -1;
            return 0;
        });
        System.out.println(Arrays.toString(arr));
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值