美文网首页设计模式
设计模式——策略模式

设计模式——策略模式

作者: 永远少年1024 | 来源:发表于2022-11-03 12:35 被阅读0次

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

    1、设计模式该怎么用

    当我们项目中出现了多个if……else的时候就可以选择使用策略模式,策略模式就是做同一件事件的不同的方法,设计模式说到底就是java多态的灵活运用。设计项目时我们一般要遵循开闭原则,即关闭修改,打开扩展,也就是说尽量别去修改现有的代码,而是对其进行扩展,这就要求我们在设计的时候需要考虑到可以进行灵活的扩展。
    

    2、策略模式-比较动物大小

    2.1、根据体重比较

    我们现在有一只猫,根据体重比较猫的大小,代码如下:

    猫的实体对象

    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 {
        // 此处通过 采用选择排序进行排序
        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++) {
                  // 此处是重点需要注意,注意看调用的方法名
                  // 此处需要根据 不同的比较方式去调用不同的方法,也就是会产生多个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;
        }
    
    }
    
    

    执行:

    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、根据身高比较

    现在我希望根据猫的身高比较猫的大小,按照常规写法,我们需要<font color='red'>在 Cat </font>对象里面在实现一个方法.

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

    修改排序的调用方法

    package com.xin.demo.strategy;
    
    public class Sort {
        // 此处通过 采用选择排序进行排序
        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++) {
                // 注意此处改成了 调用体重的方法
                // 此处需要根据 不同的比较方式去调用不同的方法,也就是会产生多个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、根据策略模式

        以上两种情况我们发现,如果在做同一件猫的大小的比较,根据不同的方式去做的时候我们需要写很多冗余的代码,且不利于扩展,如在增加一种比较方式的时候,我们需要继续进行方法的迭代,且排序方法需要在增加或者重写,此处策略主要针对的是排序部分。
    
        既然是同一件事情,不同的方式去做,那么我们可以定义一个比较器接口,通过不同的实现来完成。
    

    首先定义一个接口:

    package com.xin.demo.strategy;
    
    public interface Comparator<T> {
    
        // 比较器
        int compare(T o1, T o2);
    }
    
    

    对应的实现:

    体重:

    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> {
        // 此处通过 采用选择排序进行排序
        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++) {
                  // 重点
                    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;
        }
    
    }
    
    

    执行:

    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)};
            // 普通写法
            Sort.selectionSort(cat);
            System.out.println(Arrays.toString(cat));
    
            // 策略模式写法
            StrategySort<Cat> strategySort = new StrategySort<>();
            // 传进去需要比较的对象,以及对应的策略,也就是对应的比较方式
            // 根据身高比较
            strategySort.selectionSort(cat, new CatCompareToHeight());
            System.out.println("根据height排序:"+Arrays.toString(cat));
    
            //根据体重进行比较
            strategySort.selectionSort(cat, new CatCompareToWeight());
            System.out.println("根据weight排序:"+Arrays.toString(cat));
    
        }
    }
    
    

    2.4、可以比较任何动物的大小

    package com.xin.demo.strategy;
    
    import java.util.Arrays;
    
    public class OperatorMain {
        public static void main(String[] args) {
            // 现在我们不仅可以比较猫的大小,还可以比较任何一个动物的大小
            // lambda 表达式写法
            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));
        }
    }
    
    
    

    相关文章

      网友评论

        本文标题:设计模式——策略模式

        本文链接:https://www.haomeiwen.com/subject/ofqetdtx.html