栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java设计模式之策略模式

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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.首先定义一个抽象比较接口类:

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

2.定义一个dog类

public class Dog {

    int food;

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

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

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

public class DogComparator implements Comparator {
    
    @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类:里面传比较数据的数组和比较器

public class Sorter {
    public void sort(T[] arr, Comparator 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.运行比较:

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 sorter = new Sorter<>();
        sorter.sort(a, new DogComparator());
        System.out.println(Arrays.toString(a));
    }
}

运行结果如下:

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

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

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类的比较器:

public class CatHeightComparator implements Comparator {
    @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;
    }
}
public class CatWeightComparator implements Comparator {
    @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;
    }
}

根据不同的比较器排序:

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 sorter = new Sorter<>();
        sorter.sort(a, new CatHeightComparator());
        System.out.println(Arrays.toString(a));
    }
}
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 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语句来选择这些行为的情况下,可以使用策略模式来代替这些条件语句。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1000284.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号