ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

策略模式

2022-09-04 14:02:08  阅读:165  来源: 互联网

标签:arr return 策略 weight int 模式 foot public


策略模式

应用场景:comparator

先看需求:

实现一个排序器,要求可以对传入的任意类型数组都进行排序

猫数组排序,狗数组排序,只要有大小关系就可以排序,而这个大小关系是我们人为定义的,如狗的规则可以是饭量小的排前面,猫的规则是体重小的排前面等

先看排序器类:就一个简单的公共排序方法,里边使用的一个简单的选择排序

package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 10:52
 */
public class Sorter {

    public static void sort(Comparable[] arr) {
        for (int i = 0;i < arr.length - 1;i++) {
            int minPos = i;

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

            swap(arr,i,minPos);
        }
    }

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

上面代码可能很多人会有疑问,怎么传的是Comoarable数组?

这就是java设计模式的精华了,要保证代码的通用性,一定要想到接口(多态)。所谓java的设计模式,其实就是接口的各种玩法

我们先看看这个接口

package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 10:51
 */
public interface Comparable {
    int CompareTo(Object o);
}

接口是什么?接口描述的是一些事物所具有的共同特征,Comparable即顾名思义是指具有可比较性的一类事物,猫类实现这个接口表示的是猫是可比较的,即可以排序的,狗也如此。只是它们实现不一样,即多态

下面是猫狗类,重点看一下compareTo方法即可

package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 11:00
 */
public class Cat implements Comparable{
    int weight,height;

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

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


    @Override
    public int CompareTo(Object o) { // 重点在这,其他不用看
       Cat cat = (Cat) o;
       if (this.weight < cat.weight) return -1;
       else if (this.weight > cat.weight) return 1;
       else return 0;
    }
}


package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 11:06
 */
public class Dog implements Comparable {

    int foot;// 饭量

    @Override

    public int CompareTo(Object o) {
        Dog d = (Dog)o; // 这里还有些异常,o传进来如果是cat,会报ClassCastException
        if (this.foot < d.foot) return -1;
        else if (this.foot > d.foot) return 0;
        else return 0;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "foot=" + foot +
                '}';
    }

    public Dog(int foot) {
        this.foot = foot;
    }
}

下面是测试

public class Main {
    public static void main(String[] args) {
        Cat[] cats = {new Cat(4,3),new Cat(3,4)};
        Dog[] dogs = {new Dog(2),new Dog(4)};

        Sorter.sort(cats);
        Sorter.sort(dogs);
        System.out.println(Arrays.toString(cats));
        System.out.println(Arrays.toString(dogs));


    }
}

![image-20220904113413541](D:\Download\尚硅谷\msb\designer pattern\img\image-20220904113413541.png)

泛型优化,保证谁用compare方法,就传什么类型参数,比如猫调用,就只能传猫类型,而不会传狗类型,这样就不会出现类转换异常了

package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 10:51
 */
public interface Comparable<T> { 
    int CompareTo(T o);
}

修改猫狗后的代码

public class Cat implements Comparable<Cat>{
    int weight,height;

    @Override
    public int CompareTo(Cat cat) {
        if (this.weight < cat.weight) return -1;
        else if (this.weight > cat.weight) return 1;
        else return 0;
    }
    ...
}

public class Dog implements Comparable<Dog> {

    int foot;// 饭量

    @Override
    public int CompareTo(Dog d) {
        if (this.foot < d.foot) return -1;
        else if (this.foot > d.foot) return 0;
        else return 0;
    }
    ...
}

搞这么久,其实这还没到策略模式哈,我们实现的Comparable,而策略模式体现在Comparator,不过,别急,

设计模式理论上都差不多的,其最终目的都是帮助我们写出优雅以及便于维护的代码

现在正式进入策略模式

先说以下Comparable接口,确实是帮助我们达到了对任意对象数组实现排序,但是依然是不够灵活的,因为总要

去各个类里实现Comparable接口,耦合度比较高。例如,我要换一种排序规则呢?比如猫之前是按照体重排序,我现在

想要按照身高排序该怎么办?直接改接口实现非常不灵活。说白了,我想要猫的比较大小的策略可以灵活指定,该怎么实现?

这时候策略模式隆重登场啦。我们要知道,在设计的指导思想里边,有一个非常重要的概念,对扩展开放,对修改关闭

Comparator接口

package org.ali.strategy;

/**
 * Author: lury
 * Date: 2022-09-04 12:44
 */
public interface Comparator<T> {
    int compare(T o1,T o2);
}
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[i]) == -1 ? j : minPos;
            }

            swap(arr,i,minPos);
        }
    }
  }

测试

package org.ali.strategy;

import java.util.Arrays;

/**
 * Author: lury
 * Date: 2022-09-04 11:08
 */
public class Main {
    public static void main(String[] args) {
        Cat[] cats = {new Cat(4,7),new Cat(3,4)};
        Dog[] dogs = {new Dog(2),new Dog(4)};

        new Sorter<Cat>().sort(cats,((o1, o2) ->
            o1.height - o2.height < 0 ? -1 : 1
        ));

        System.out.println(Arrays.toString(cats));

    }
}

image-20220904132019234

神奇吧?怎么做到的,就是在需要灵活变换的比较方法中,多加一个接口,把接口的实现留白给用户实现

类图

![image-20220904133157807](D:\Download\尚硅谷\msb\designer pattern\img\image-20220904133157807.png)

说白了就是 对策略进行开放拓展,排序的话,就可以有很多种策略

实际怎么运用?去代替if

标签:arr,return,策略,weight,int,模式,foot,public
来源: https://www.cnblogs.com/mybloger/p/16654973.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有