java策略模式 工厂模式_策略模式及使用Spring实现策略模式+工厂模式-Go语言中文社区...

一、策略模式

策略模式定义了一组算法,将每个算法都封装起来,并且使它们之间可以互换

1、策略模式主要角色

java策略模式 工厂模式_策略模式及使用Spring实现策略模式+工厂模式-Go语言中文社区..._第1张图片

主要角色如下:

封装角色(Context):也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访问,封装可能存在的变化

抽象策略角色(Strategy):策略家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属性

具体策略角色(ConcreteStrategy):实现抽象策略中的操作,该类含有具体的算法

2、实现策略模式

//抽象策略角色

public interface Strategy {

//策略模式的运算法则

void doSomething();

}

//具体策略角色

public class ConcreteStrategy1 implements Strategy {

@Override

public void doSomething() {

System.out.println("具体策略1的运算法则...");

}

}

//具体策略角色

public class ConcreteStrategy2 implements Strategy {

@Override

public void doSomething() {

System.out.println("具体策略2的运算法则...");

}

}

//封装角色

public class Context {

//抽象策略

private Strategy strategy;

//构造函数设置具体策略

public Context(Strategy strategy) {

this.strategy = strategy;

}

//封装后的策略方法

public void doAnything() {

this.strategy.doSomething();

}

}

public class Client {

public static void main(String[] args) {

//声明一个具体的策略

Strategy strategy = new ConcreteStrategy1();

//声明上下文对象

Context context = new Context(strategy);

//执行封装后的方法

context.doAnything();

}

}

执行结果如下:

具体策略1的运算法则...

二、使用Spring实现策略模式+工厂模式

1、实现策略类

public interface Strategy {

//策略模式的运算法则

void doSomething();

}

@Component

public class ConcreteStrategy1 implements Strategy {

@Override

public void doSomething() {

System.out.println("具体策略1的运算法则...");

}

@Override

public String toString() {

return "具体策略1";

}

}

@Component

public class ConcreteStrategy2 implements Strategy {

@Override

public void doSomething() {

System.out.println("具体策略2的运算法则...");

}

@Override

public String toString() {

return "具体策略2";

}

}

@Component

public class DefaultStrategy implements Strategy {

@Override

public void doSomething() {

System.out.println("默认策略的运算法则...");

}

@Override

public String toString() {

return "默认策略";

}

}

2、实现工厂类

@Component

public class StrategyFactory {

//Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类

@Autowired

private Map strategyMap;

public Strategy getBy(String strategyName) {

return strategyMap.get(strategyName);

}

}

Spring会自动将Strategy接口的实现类注入到这个Map中(前提是实现类得是交给Spring 容器管理的),这个Map的key为bean id,可以用@Component(value = "xxx")的方式设置,如果直接用默认的方式的话,就是首字母小写。value值则为对应的策略实现类

java策略模式 工厂模式_策略模式及使用Spring实现策略模式+工厂模式-Go语言中文社区..._第2张图片

测试类:

@SpringBootTest

class SpringbootDemoApplicationTests {

@Autowired

private ApplicationContext context;

@Test

public void test() {

context.getBean(StrategyFactory.class).getBy("concreteStrategy1").doSomething();

context.getBean(StrategyFactory.class).getBy("concreteStrategy2").doSomething();

}

}

执行结果如下:

具体策略1的运算法则...

具体策略2的运算法则...

3、别名转换

上面测试类调用的使用使用的bean id,实际业务中应该是将传入的code转义成对应的策略类的bean id

@Component

@PropertySource("classpath:application.properties")

@ConfigurationProperties(prefix = "strategy")

public class StrategyAliasConfig {

private HashMap aliasMap;

public static final String DEFAULT_STATEGY_NAME = "defaultStrategy";

public HashMap getAliasMap() {

return aliasMap;

}

public void setAliasMap(HashMap aliasMap) {

this.aliasMap = aliasMap;

}

public String of(String entNum) {

return aliasMap.get(entNum);

}

}

配置文件application.properties

strategy.aliasMap.strategy1=concreteStrategy1

strategy.aliasMap.strategy2=concreteStrategy2

@Component

public class StrategyFactory {

@Autowired

private StrategyAliasConfig strategyAliasConfig;

//Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类

@Autowired

private Map strategyMap;

//找不到对应的策略类,使用默认的

public Strategy getBy(String strategyName) {

String name = strategyAliasConfig.of(strategyName);

if (name == null) {

return strategyMap.get(StrategyAliasConfig.DEFAULT_STATEGY_NAME);

}

Strategy strategy = strategyMap.get(name);

if (strategy == null) {

return strategyMap.get(StrategyAliasConfig.DEFAULT_STATEGY_NAME);

}

return strategy;

}

}

测试类:

@SpringBootTest

class SpringbootDemoApplicationTests {

@Autowired

private ApplicationContext context;

@Test

public void test() {

context.getBean(StrategyFactory.class).getBy("strategy1").doSomething();

context.getBean(StrategyFactory.class).getBy("strategy2").doSomething();

}

}

执行结果如下:

具体策略1的运算法则...

具体策略2的运算法则...

参考:

《设计模式之禅》

https://mp.weixin.qq.com/s/cc4Slm0Ta22PShYuKpO2mQ

你可能感兴趣的:(java策略模式,工厂模式)