java开发中经常会应用设计模式,下面温习策略模式
策略模式定义了算法族(簇,即多个),将单个算法分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的的客户。这个策略模式的定义是不是有点抽象呢?那我们来看点通俗易懂的比喻:小伙子追求学校里的校花,为了获得女孩子的芳心,准备了不同的策略,有请吃饭、唱歌、滑雪、看电影、逛街买衣服等,若是请吃饭不行,就请她去滑雪,总有一种会讨得女孩子的开心,最后走到一起~
业务场景:处理文件,但不知道文件的类型,可能是xml、或txt、或json,需要采用不同的算法进行解析。
若采用if。。else。。则违背了开闭原则和职责单一原则,因为新增加一种类型的文件,则需要修改原来代码。
策略模式使用方式:1定义一个接口或抽象类,里面两个方法(一个匹配类型,一个替换)2不同策略的实现类3使用策略模式
代码示例
1定义一个接口
public interface IFileStrategy {
//属于哪种文件解析类型
String fileType();
//封装的公用算法(具体的解析方法)
void resolve(Object objectparam);
}
2实现类
@Component
public class AFileResolve implements IFileStrategy {
@Override
public String fileType() {
return "A";
}
@Override
public void resolve(Object objectparam) {
System.out.println(String.format("A 类型解析文件,参数:%s",objectparam.toString()));
//A类型解析具体逻辑
}
}
@Component
public class BFileResolve implements IFileStrategy {
@Override
public String fileType() {
return "B";
}
@Override
public void resolve(Object objectparam) {
System.out.println(String.format("B 类型解析文件,参数:%s",objectparam));
//B类型解析具体逻辑
}
}
@Component
public class DefaultFileResolve implements IFileStrategy {
@Override
public String fileType() {
return "DEFAULT";
}
@Override
public void resolve(Object objectparam) {
System.out.println(String.format("默认类型解析文件,参数:%s",objectparam));
//默认类型解析具体逻辑
}
}
3封装策略模式
@Component
public class StrategyService implements ApplicationContextAware {
private Map<String, IFileStrategy> iFileStrategyMap = new ConcurrentHashMap<>();
//把不同策略放到map
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Map<String, IFileStrategy> map = applicationContext.getBeansOfType(IFileStrategy.class);
map.values().forEach(iFileStrategy -> iFileStrategyMap.put(iFileStrategy.fileType(), iFileStrategy));
}
public void resolveFile(String fileType, Object objectParam) {
IFileStrategy iFileStrategy = iFileStrategyMap.get(fileType);
if (iFileStrategy != null) {
iFileStrategy.resolve(objectParam);
}
}
}
使用测试
@Test
void test() {
IFileStrategy iFileStrategy = new BFileResolve();
iFileStrategy.resolve("test");
}
或
@Autowired
private StrategyService strategyService;
@Test
void contextLoads() {
strategyService.resolveFile("A","strategy");
}
其实也可以是工厂模式,StrategyService
//把所有的文件类型解析的对象,放到map,需要使用时,信手拈来即可。这就是工厂模式的一种体现啦
//或构造不同的工厂对象
IFileResolveFactory fileResolveFactory;
if(fileType=“A”){
fileResolveFactory = new AFileResolve();
}else if(fileType=“B”){
fileResolveFactory = new BFileResolve();
}else{
fileResolveFactory = new DefaultFileResolve();
}
fileResolveFactory.resolve();