设计模式-Strategy模式

策略模式(Strategy Pattern),属于行为型模式,指的是定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。

image

一个例子

前一阵子忙活落户的事,发现不同人群落户的政策也不太一样,如果要写一段程序针对不同人群做不同的处理该是什么样呢。

传统做法

一般在工作中遇到这种不同情况不同处理的时候首先会想到if-else结构(当然也会有switch)。

落户处理类

public class SettleHandler {
    /**
     * 处理户口
     * @param crowdType 人群类型:大学生,创业者,其他
     */
    public static void handleSettle(String crowdType) {
        if (CrowdTypeEnum.COLLEGESTUDENT.getCode().equals(crowdType)) {
            //一系列处理操作
            System.out.println("全国高等院校在校学生(教育部学信网在册人员),均可迁入本市落户。");
        } else if (CrowdTypeEnum.PIONEER.getCode().equals(crowdType)) {
            //一系列处理操作
            System.out.println("凡在我市依法注册登记并正常经营的市场主体,其法定代表人、员工和个体经营者可迁入本市落户。");
        } else if (CrowdTypeEnum.OTHER.getCode().equals(crowdType)) {
            //一系列处理操作
            System.out.println("详讯本地公安局");
        }
    }
}

根据人群类型选择不同的处理策略

        //大学生
        String myCrowdType = CrowdTypeEnum.COLLEGESTUDENT.getCode();
        System.out.print("大学生落户政策:");
        SettleHandler.handleSettle(myCrowdType);
        //创业者
        String myCrowdType1 = CrowdTypeEnum.PIONEER.getCode();
        System.out.print("创业者落户政策:");
        SettleHandler.handleSettle(myCrowdType1);
大学生落户政策:全国高等院校在校学生(教育部学信网在册人员),均可迁入本市落户。
创业者落户政策:凡在我市依法注册登记并正常经营的市场主体,其法定代表人、员工和个体经营者可迁入本市落户。

可以发现上面写法的弊端:如果要增加一个人群类型,就要对应增加一个处理规则,也就是要多加一个if判断,如果规则变得很多,这将变得非常麻烦。

策略模式

策略模式核心是将算法策略独立出来以便达到易扩展的目的。

image
落户处理策略基类

public interface Strategy {
    /**
     * 策略处理方法
     */
    void handle();
}

大学生落户处理策略

public class CollegeStudentStrategy implements Strategy {
    /**
     * 策略处理类
     *
     */
    @Override
    public void handle() {
        System.out.println("全国高等院校在校学生(教育部学信网在册人员),均可迁入本市落户。");
    }
}

创业者落户处理策略

public class PioneerStrategy implements Strategy {
    /**
     * 策略处理方法
     *
     */
    @Override
    public void handle() {
        System.out.println("凡在我市依法注册登记并正常经营的市场主体,其法定代表人、员工和个体经营者可迁入本市落户。");
    }
}

其他落户处理策略

public class OtherStrategy implements Strategy {
    /**
     * 策略处理方法
     *
     */
    @Override
    public void handle() {
        System.out.println("详讯本地公安局。");
    }
}

策略处理上下文

public class StrategyContext {
    private Strategy strategy;

    public StrategyContext(Strategy strategy) {
        this.strategy = strategy;
    }
    public void handle() {
        strategy.handle();
    }
}

不同情况不同策略处理

//大学生落户
        Strategy strategy = new CollegeStudentStrategy();
        StrategyContext context = new StrategyContext(strategy);
        System.out.print("大学生落户政策:");
        context.handle();
        //创业者落户
        Strategy strategy1 = new PioneerStrategy();
        StrategyContext context1 = new StrategyContext(strategy1);
        System.out.print("大学生落户政策:");
        context1.handle();
        //其他落户
        Strategy strategy2 = new OtherStrategy();
        StrategyContext context2 = new StrategyContext(strategy2);
        System.out.print("其他落户政策:");
        context2.handle();
大学生落户政策:全国高等院校在校学生(教育部学信网在册人员),均可迁入本市落户。
大学生落户政策:凡在我市依法注册登记并正常经营的市场主体,其法定代表人、员工和个体经营者可迁入本市落户。
其他落户政策:详讯本地公安局。

总结

  • 很明显能感觉到将算法单独拆分出来之后更容易应对后续增加不同算法的问题。
  • 策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。
  • 策略模式主要解决的是不同算法之间如何组织如何调度算法。
  • 它遵循了多用组合,少用继承、针对接口编程,不针对实现编程两个设计原则。

当然把使用什么算法交给用户,就意味着用户必须理解这些算法的区别,才能恰当选择算法。后续可以结合工厂模式来解决这个问题。


你可以在这里获取相关代码:设计模式-Strategy模式

原文地址:https://www.cnblogs.com/xuxiaojian/p/11475120.html