java设计模式之策略模式

一、定义

策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

二、为什么使用策略类

实现某一个功能有多条途径,每一条途径对应一种类似又抽象算法,此时我们可以使用一种设计模式来实现灵活地选择解决途径,也能够方便地增加新的解决途径。

三、结构图

在这里插入图片描述

四、引出策略模式

例如我们对一个int类型数组进行排序:

public class Main {
    public static void main(String[] args) {
        int[] a = {9, 6, 7, 5, 3, 12, 56, 120};
        Sorter sorter = new Sorter();
        sorter.sort(a);
        System.out.println(Arrays.toString(a));
    }
}
public class Sorter {

    public static void sort(int[] 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] < arr[minPos] ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }

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

运行结果如下:

[3, 5, 6, 7, 9, 12, 56, 120]

以上一个Sorter类定义了sort方法,形式参数是int类型的数组,可以实现排序,那么问题来了,我们现在需要对一个double类型,float类型排序呢,该如何做?是不是得再写个sort方法,形参定义为double和float类型呢?

下面举例,我们现在需要对Cat,dog,Car等排序,且每种类的排序方式都是不同的:
1.首先定义一个抽象比较接口类:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 23:21
 * @Description :比较器接口
 */
public interface Comparator<T> {
    int compare(T o1, T o2);
}

2.定义一个dog类

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 23:12
 * @Description :
 */
public class Dog {

    int food;

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

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

3.编写dog类的比较规则类:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 23:24
 * @Description :
 */
public class DogComparator implements Comparator<Dog> {
    /**
     * Dog类比较器
     * @param o1
     * @param o2
     * @return
     */
    @Override
    public int compare(Dog o1, Dog o2) {
        if (o1.food < o2.food) return -1;
        else if (o1.food > o2.food) return 1;
        else return 0;
    }
}

4.定义sort类:里面传比较数据的数组和比较器

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 22:49
 * @Description :对数组进行排序算法
 */
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);
        }
    }

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

5.运行比较:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 22:49
 * @Description :
 */
public class Main {
    public static void main(String[] args) {
//        int[] a = {9, 6, 7, 5, 3, 12, 56, 120};
        Dog[] a = {new Dog(3), new Dog(1), new Dog(5)};
        Sorter<Dog> sorter = new Sorter<>();
        sorter.sort(a, new DogComparator());
        System.out.println(Arrays.toString(a));
    }
}

运行结果如下:

[Dog{food=1}, Dog{food=3}, Dog{food=5}]

再比如,我们要对Cat对象进行排序,并有两种比较方式:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 22:49
 * @Description :
 */
public class Cat {

    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 +
                '}';
    }
}

定义两种Cat类的比较器:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 23:33
 * @Description :Cat类比较器2,根据高度比较
 */
public class CatHeightComparator implements Comparator<Cat> {
    @Override
    public int compare(Cat o1, Cat o2) {
        if (o1.height < o2.height) return -1;
        else if (o1.height > o2.height) return 1;
        else return 0;
    }
}
/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 23:33
 * @Description :Cat类比较器1,根据重量比较
 */
public class CatWeightComparator implements Comparator<Cat> {
    @Override
    public int compare(Cat o1, Cat o2) {
        if (o1.weight < o2.weight) return -1;
        else if (o1.weight > o2.weight) return 1;
        else return 0;
    }
}

根据不同的比较器排序:

/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 22:49
 * @Description :
 */
public class Main {
    public static void main(String[] args) {
//        int[] a = {9, 6, 7, 5, 3, 12, 56, 120};
        Cat[] a = {new Cat(3,3), new Cat(1,1), new Cat(5,5)};
        Sorter<Cat> sorter = new Sorter<>();
        sorter.sort(a, new CatHeightComparator());
        System.out.println(Arrays.toString(a));
    }
}
/**
 * @Author: chuxia0811
 * @Date: 2022/6/28 22:49
 * @Description :
 */
public class Main {
    public static void main(String[] args) {
//        int[] a = {9, 6, 7, 5, 3, 12, 56, 120};
        Cat[] a = {new Cat(3,3), new Cat(1,1), new Cat(5,5)};
        Sorter<Cat> sorter = new Sorter<>();
        sorter.sort(a, new CatWeightComparator());
        System.out.println(Arrays.toString(a));
    }
}

由上面可见,我们只需要比较时传不同的比较器规则类进去即可按我们的比较器定义的相应的规则进行比较了。

五、策略模式的优缺点:

策略模式的优点:

1、定义一系列算法

2、避免多重条件语句

3、更好的扩展性

策略模式的缺点:

1、客户必须了解每一种策略的不同

2、增加了对象数目

3、只适合扁平的算法结构

六、何时选用策略模式

1、出现有许多相关的类,仅仅是行为有差别的情况下,可以使用策略模式来使用多个行为中的一个来配置一个类的方法,实现算法动态切换。

2、实现同一个算法,有很多不同实现的情况下,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次。

3、需要封装算法中,有与算法相关数据的情况下,可以使用策略模式来避免暴露这些跟算法相关的数据结构。

4、出现抽象一个定义了很多行为的类,并且是通过多个if-else语句来选择这些行为的情况下,可以使用策略模式来代替这些条件语句。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初夏0811

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值