设计模式之策略模式(Strategy)

你要对int类型的数组进行排序,你可能写一个排序类,专门来排序int类型的数组

public class Sorter {

    public 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);
        }
    }

    //sort(int)

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

如果要对double类型,float类型的数组进行排序呢? --> 很容易想到的是,再写两个类,来对double,float进行排序。
但是如果要对Cat,Dog进行排序呢?怎么办? --> 写多个排序类很复杂

1.使用Comparable接口,任何人想要我进行排序,都要实现Comparable接口,里面有compareTo方法。Cat和Dog类都去实现Comparable接口

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

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

    public int compareTo(Cat c) {

        if(this.weight < c.weight) return -1;
        else if(this.weight > c.weight) return 1;
        else return 0;
    }

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

Sorter类传入Comparable的子类:

public class Sorter {

    public 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[i].compareTo(arr[minPos]) == -1 ? j : minPos;
            }
            swap(arr, i, minPos);
        }
    }

    //sort(int)

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

Comparable接口不是策略模式,不够灵活,现在Cat里面是用weight比较大小,如果想用height比较大小,该怎么办?
我想猫的比较大小的策略可以灵活的指定 --> 怎么做?

有一种比较简单的想法,把以前的代码删了,重新写一个用height比较的Cat类 --> 不好
在设计模式里面有一种开闭原则:
对修改关闭,对扩展开放 - 开闭原则。 不修改原来的代码,但是可以扩展原来的代码。

2.使用Comparator比较器,Comparator比较器使用了策略模式
Comparator里面有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;
    }
}

Dog类实现比较器:

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

Cat根据height和weight分别实现不同的比较器:

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

如果想要添加新的比较类型进来,Sort方法是不用变的,只需要添加一些新的策略进来,也就是添加新的Comparator

策略模式封装的是做同一件事情的不同方式

怎么用到实际项目中? --> 不同的支付方式(微信,支付宝,银行卡等),可以使用策略模式,支付的时候传进来自己的支付方式

定义一个接口,里面有个抽象的支付方法,其它不同的支付方式(微信,支付宝,银行卡)实现该接口,实现不同的支付方法。

策略模式的好处,扩展性好。

你可能感兴趣的:(设计模式,设计模式,策略模式)