侧边栏壁纸
博主头像
昂洋编程 博主等级

鸟随鸾凤飞腾远,人伴贤良品自高

  • 累计撰写 71 篇文章
  • 累计创建 79 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

策略模式

Administrator
2022-06-25 / 0 评论 / 0 点赞 / 40 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于2024-06-14,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

策略模式,即在多个对象有相同的操作的时候,我们可以通过使用策略模式来简化代码及扩展,这样遵循了开闭原则,以下以 排序 这个动作进行举例。另外设计模式大多都是多态的一张体现

具体策略模式有什么作用,以排序作为例子,假设现在我们需要对Cat进行排序,通常情况下我们只需要实现Comparator接口并重写compare方法即可实现排序,但是如果我们现在想使用多种排序方式,刚开始我们用Cat的重量进行排序,现在我们要根据身高排序,或者我们现在想要对Dog进行多种方式的排序

上面的举例有两个核心,待排序的对象数组、排序的方式

假设我们有一个Cat类

@Getter
@Setter
@ToString
@AllArgsConstructor
public class Cat {

    /**
     * 体重
     */
    private Integer weight;

    /**
     * 身高
     */
    private Integer height;

}

然后我们有一个排序类

package com.imysh.zmy.mca.designpattern.strategy;

import java.util.Comparator;

/**
 * @author zhangmy
 * @date 2022/6/25 8:06
 * @description
 */
public class Sorter<T> {

    /**
     * 排序
     * @param arr 待排序对象数组
     * @param comparator 比较器
     */
    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);
        }
    }

    /**
     * 内部方法 -- 交换顺序
     * @param arr
     * @param i
     * @param j
     */
    private void swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

Sorter类提供泛型T,意思是可以传不同的类,比如我们下面还会用到的Dog类
然后其中的sort方法支持实现了Comparator接口的比较
以上两点就解决了前面提到的两个核心

现在我们对Cat进行重量排序

Cat[] cats = {new Cat(1, 3), new Cat(5, 2), new Cat(2, 1)};
// 猫按重量排序
Sorter<Cat> catSorter1 = new Sorter<>();
catSorter1.sort(cats, (o1, o2) -> {
	if (o1.getWeight() < o2.getWeight()) {
		return -1;
	} else if (o1.getWeight() > o2.getWeight()) {
		return 1;
	} else {
		return 0;
	}
});
System.out.println(Arrays.toString(cats));

我们将Cat对象数组和自定义的按weight比较的比较器传给sort方法

同样,比如我们想要通过height进行排序,我们可以照葫芦画瓢

	// 猫按身高排序
        Sorter<Cat> catSorter2 = new Sorter<>();
        catSorter2.sort(cats, (o1, o2) -> {
            if (o1.getHeight() < o2.getHeight()) {
                return -1;
            } else if (o1.getHeight() > o2.getHeight()) {
                return 1;
            } else {
                return 0;
            }
        });
        System.out.println(Arrays.toString(cats));

假设我们还有一个Dog类

@Getter
@Setter
@ToString
@AllArgsConstructor
public class Dog {

    /**
     * 饭量
     */
    private Integer food;

    /**
     * 体长
     */
    private Integer length;
}

同样我们可以按照food排序

	Dog[] dogs = {new Dog(5, 2), new Dog(2, 3), new Dog(6, 5)};
        // 狗按饭量排序
        Sorter<Dog> dogSorter1 = new Sorter<>();
        dogSorter1.sort(dogs, (o1, o2) -> {
            if (o1.getFood() < o2.getFood()) {
                return -1;
            } else if (o1.getFood() > o2.getFood()) {
                return 1;
            } else {
                return 0;
            }
        });
        System.out.println(Arrays.toString(dogs));

也可以按照length排序

	// 狗按体长排序
        Sorter<Dog> dogSorter2 = new Sorter<>();
        dogSorter2.sort(dogs, (o1, o2) -> {
            if (o1.getLength() < o2.getLength()) {
                return -1;
            } else if (o1.getLength() > o2.getLength()) {
                return 1;
            } else {
                return 0;
            }
        });
        System.out.println(Arrays.toString(dogs));

综上,策略模式适用于在对多个对象进行相同的动作的时候,这样我们就可以将对象和动作提炼成参数,写成通用,动作一定写成接口,这样实现就可以有多种多样
像官方Collections.sort()就用到了策略模式

    @SuppressWarnings({"unchecked", "rawtypes"})
    public static <T> void sort(List<T> list, Comparator<? super T> c) {
        list.sort(c);
    }
0

评论区