Strategy策略模式

作用

我们也有很多中方法来实现一个功能,但是我们需要一种简单、高效的方式来实现它,使得系统能够非常灵活,这就是策略模式。
策略模式其实很简单,就是针对不同的场景,做出不同的处理策略。将一系列行为封装起来,被封装起来的行为具有独立性外部不可改变其特性。

遵循了开闭原则,不需要改动旧代码,更方便维护。

使用方式

为了方便大家真正体会策略模式的好处,这里给出一系列的变换过程,方便大家对比。

实体类:

@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Apple {
    private String color;
    private int weight;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
public static class Pear {
    private String color;
    private int weight;
}

ps:这里的注解使用了 lombok 。

实例化对象:

public static void main(String[] args) {
    Apple[] apples = {new Apple("green", 13)
        , new Apple("red", 16)
        , new Apple("red", 20)};
    
    Pear[] pears = {new Pear("green", 13)
        , new Pear("yellow", 16)
        , new Pear("yellow", 20)};

}

提出需求:输出apples中绿色的苹果,输出pears里面重量大于15的梨子。

public static void main(String[] args) {
    
        ~~~~~~~~~~~~~~~
            
        compareColor(apples, "green");
        compareWeight(pears, 15);
    }

public static void compareColor(Apple[] apples, String color) {
    for (Apple apple : apples) {
        if (color.equals(apple.getColor())) {
            System.out.println(apple);
        }
    }
}

public static void compareWeight(Pear[] pears, int weight) {
    for (Pear pear : pears) {
        if (pear.getWeight() > weight) {
            System.out.println(pear);
        }
    }
}

ps:如果方法很多,我们一般是再封装一个方法,根据传的值,使用if … else if … else if …来调用下方进行筛选的方法。

 public static <T> void compare(Object[] o, String s) {
     if ("apple".equals(s)) compareColor((Apple[]) o, "green");
     else if ("pear".equals(s)) compareWeight((Pear[]) o, 15);
 }

上面这种方式很简单,但是他们的代码其实是冗余的,他们本质上都是对一个数组做一个筛选的行为。而且如果我们需要对很多不同的类做不同的筛选行为,那么我们就要创建很多不同的方法进行调用来满足我们的需求。

那我们能不能只用调用同一个方法,就可以满足我们的需求呢,这里我们就可以使用策略模式了。

分析:

  • 第一个参数:我们应该能考虑到需要用一个能动态的接收不同类的关键字,这时候我们有两个选择:Object和泛型T。Object是所有类的父类,但是我们使用的时候还需要强制向下转型,所以我们选择泛型T会更方便。
  • 第二个参数:本质上这个参数就是我们需要进行的行为(比如筛选颜色为绿色的苹果,筛选重量大于15的梨子),所以我们可以把这个行为提取成一个接口,然后根据不同的需求去实现这个接口。

总结:根据上面的的分析,我们现在需要一个接口,根据不同的需求来创建类并实现这个接口,创建一个统一的调用方法。

策略模式实现:

public static void main(String[] args) {
    
	~~~~~~~~~~~~~~~
    
    filter(apples, new ApplesGreenFilter());
    filter(pears, new PearsWeightGt15Filter());
}

public static <T> void filter(T[] arr, Comparator comparator) {
    for (T t : arr) {
        if (comparator.comparator(t)) {
            System.out.println(t);
        }
    }
}

public interface Comparator<T> {
    boolean comparator(T t);
}

public static class ApplesGreenFilter implements Comparator<Apple> {
    @Override
    public boolean comparator(Apple apple) {
        return "green".equals(apple.getColor());
    }
}

public static class PearsWeightGt15Filter implements Comparator<Pear> {
    @Override
    public boolean comparator(Pear pear) {
        return pear.getWeight() > 15;
    }
}

当然java1.8的时候我们也可以使用lambda表达式来简化:

public static void main(String[] args) {
    
	~~~~~~~~~~~~~~~
    
    filter(apples, apple -> "green".equals(apple.getClass()));
    filter(pears, pear -> pear.getWeight() > 15);
}

public static <T> void filter(T[] arr, Comparator comparator) {
    for (T t : arr) {
        if (comparator.comparator(t)) {
            System.out.println(t);
        }
    }
}

public interface Comparator<T> {
    boolean comparator(T t);
}

总结:
在策略模式中它将这些解决问题的方法定义成一个算法群,每一个方法都对应着一个具体的算法,这里的一个算法我就称之为一个策略。
虽然策略模式定义了算法,但是它并不提供算法的选择,即什么算法对于什么问题最合适这是策略模式所不关心的,所以对于策略的选择还是要客户来做。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值