設(shè)計(jì)模式——策略模式

所有源碼的git地址https://gitee.com/0x208_jackson/design-patterns

1、設(shè)計(jì)模式該怎么用

當(dāng)我們項(xiàng)目中出現(xiàn)了多個(gè)if……else的時(shí)候就可以選擇使用策略模式,策略模式就是做同一件事件的不同的方法,設(shè)計(jì)模式說(shuō)到底就是java多態(tài)的靈活運(yùn)用。設(shè)計(jì)項(xiàng)目時(shí)我們一般要遵循開(kāi)閉原則,即關(guān)閉修改,打開(kāi)擴(kuò)展,也就是說(shuō)盡量別去修改現(xiàn)有的代碼,而是對(duì)其進(jìn)行擴(kuò)展,這就要求我們?cè)谠O(shè)計(jì)的時(shí)候需要考慮到可以進(jìn)行靈活的擴(kuò)展。

2、策略模式-比較動(dòng)物大小

2.1、根據(jù)體重比較

我們現(xiàn)在有一只貓,根據(jù)體重比較貓的大小,代碼如下:

貓的實(shí)體對(duì)象

package com.xin.demo.strategy;

import java.io.Serializable;

public class Cat implements Serializable {
    private final int weight;
    private final int height;

    public int compareToHeight(Cat cat) {
        return this.weight - cat.weight;
    }

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

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

排序:

package com.xin.demo.strategy;

public class Sort {
    // 此處通過(guò) 采用選擇排序進(jìn)行排序
    public static void selectionSort(Cat[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
              // 此處是重點(diǎn)需要注意,注意看調(diào)用的方法名
              // 此處需要根據(jù) 不同的比較方式去調(diào)用不同的方法,也就是會(huì)產(chǎn)生多個(gè)if……else
              minIndex = arr[j].compareToHeight(arr[minIndex]) < 0 ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }

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

}

執(zhí)行:

package com.xin.demo.strategy;

import java.util.Arrays;

public class OperatorMain {
    public static void main(String[] args) {
        Cat[] a = {new Cat(23, 2),
                new Cat(14, 11),
                new Cat(5, 7),
                new Cat(1, 1)};
        Sort.selectionSort(a);
        System.out.println(Arrays.toString(a));
    }
}

2.2、根據(jù)身高比較

現(xiàn)在我希望根據(jù)貓的身高比較貓的大小,按照常規(guī)寫(xiě)法,我們需要<font color='red'>在 Cat </font>對(duì)象里面在實(shí)現(xiàn)一個(gè)方法.

package com.xin.demo.strategy;

import java.io.Serializable;

public class Cat implements Serializable {
    private final int weight;
    private final int height;
  
    public int compareToHeight(Cat cat) {
        return this.weight - cat.weight;
    }

    // 此處為新增加的 根據(jù)體重進(jìn)行比較的方法
    public int compareToWeight(Cat cat) {
        return this.weight - cat.weight;
    }

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

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

修改排序的調(diào)用方法

package com.xin.demo.strategy;

public class Sort {
    // 此處通過(guò) 采用選擇排序進(jìn)行排序
    public static void selectionSort(Cat[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
            // 注意此處改成了 調(diào)用體重的方法
            // 此處需要根據(jù) 不同的比較方式去調(diào)用不同的方法,也就是會(huì)產(chǎn)生多個(gè)if……else
                            minIndex = arr[j].compareToWeight(arr[minIndex]) < 0 ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }

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

}

2.3、根據(jù)策略模式

    以上兩種情況我們發(fā)現(xiàn),如果在做同一件貓的大小的比較,根據(jù)不同的方式去做的時(shí)候我們需要寫(xiě)很多冗余的代碼,且不利于擴(kuò)展,如在增加一種比較方式的時(shí)候,我們需要繼續(xù)進(jìn)行方法的迭代,且排序方法需要在增加或者重寫(xiě),此處策略主要針對(duì)的是排序部分。

    既然是同一件事情,不同的方式去做,那么我們可以定義一個(gè)比較器接口,通過(guò)不同的實(shí)現(xiàn)來(lái)完成。

首先定義一個(gè)接口:

package com.xin.demo.strategy;

public interface Comparator<T> {

    // 比較器
    int compare(T o1, T o2);
}

對(duì)應(yīng)的實(shí)現(xiàn):

體重:

package com.xin.demo.strategy;

public class CatCompareToHeight implements Comparator<Cat> {
    @Override
    public int compare(Cat o1, Cat o2) {
        return o1.height - o2.height;
    }
}

身高:

package com.xin.demo.strategy;

public class CatCompareToWeight implements Comparator<Cat> {
    @Override
    public int compare(Cat o1, Cat o2) {
        return o1.weight - o2.weight;
    }
}

排序方法:

package com.xin.demo.strategy;

public class StrategySort<T> {
    // 此處通過(guò) 采用選擇排序進(jìn)行排序
    public void selectionSort(T[] arr, Comparator<T> comparator) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
              // 重點(diǎn)
                minIndex = comparator.compare(arr[j], arr[minIndex]) < 0 ? j : minIndex;
            }
            swap(arr, i, minIndex);
        }
    }

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

}

執(zhí)行:

package com.xin.demo.strategy;

import java.util.Arrays;

public class OperatorMain {
    public static void main(String[] args) {

        Cat[] cat = {new Cat(3, 4),
                new Cat(14, 11),
                new Cat(5, 17),
                new Cat(1, 2)};
        // 普通寫(xiě)法
        Sort.selectionSort(cat);
        System.out.println(Arrays.toString(cat));

        // 策略模式寫(xiě)法
        StrategySort<Cat> strategySort = new StrategySort<>();
        // 傳進(jìn)去需要比較的對(duì)象,以及對(duì)應(yīng)的策略,也就是對(duì)應(yīng)的比較方式
        // 根據(jù)身高比較
        strategySort.selectionSort(cat, new CatCompareToHeight());
        System.out.println("根據(jù)height排序:"+Arrays.toString(cat));

        //根據(jù)體重進(jìn)行比較
        strategySort.selectionSort(cat, new CatCompareToWeight());
        System.out.println("根據(jù)weight排序:"+Arrays.toString(cat));

    }
}

2.4、可以比較任何動(dòng)物的大小

package com.xin.demo.strategy;

import java.util.Arrays;

public class OperatorMain {
    public static void main(String[] args) {
        // 現(xiàn)在我們不僅可以比較貓的大小,還可以比較任何一個(gè)動(dòng)物的大小
        // lambda 表達(dá)式寫(xiě)法
        StrategySort<Dog> dogStrategySort = new StrategySort<>();
        Dog[] dogs = {new Dog(3, 9),
                new Dog(1, 11),
                new Dog(4, 1),
                new Dog(2, 2)};
        dogStrategySort.selectionSort(dogs, new Comparator<Dog>() {
            @Override
            public int compare(Dog o1, Dog o2) {
                return o1.height - o2.height;
            }
        });
        System.out.println(Arrays.toString(dogs));
    }
}


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容