策略模式
大部分场景,我们喜欢用IF-ELSE 或者swich解决很多问题。如果我们采用策略模式,可以方便很多
比如我们有个场景,需要分析不同文件
Show Your Code
1、定义接口
public interface Parser {
String parse(String filePath);
}
2、接口实现
/**
* @desc PDF解析
**/
@Component(ContentTypeEnum.TypeConstants.PDF_PARSER)
public class PDFParser implements Parser{
@Override
public String parse(String filePath) {
return ContentTypeEnum.TypeConstants.PDF_PARSER;
}
}
/**
* @desc 文本解析
**/
@Component(ContentTypeEnum.TypeConstants.TEXT_PARSER)
public class TextParser implements Parser {
@Override
public String parse(String filePath) {
return ContentTypeEnum.TypeConstants.TEXT_PARSER;
}
}
/**
* @desc word解析
**/
@Component(ContentTypeEnum.TypeConstants.WORD_PARSER)
public class WordParser implements Parser{
@Override
public String parse(String filePath) {
return ContentTypeEnum.TypeConstants.WORD_PARSER;
}
}
3、定义枚举
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum ContentTypeEnum {
WORD(TypeConstants.WORD_PARSER),
PDF(TypeConstants.PDF_PARSER),
TEXT(TypeConstants.TEXT_PARSER);
private String parserName;
@Override
public String toString() {
return this.parserName;
}
public interface TypeConstants {
/**PDF标识 */
String PDF_PARSER = "pdfParser";
/**word标识 */
String WORD_PARSER = "wordParser";
/**text标识 */
String TEXT_PARSER = "textParser";
}
}
4、客户端定义
@Service
public class ParserClient {
/**
* 通过spring IOC bean 构造器注入 Map
* 把接口Parser下的实现类,put到map中
*/
private final Map<String,Parser> parserMapFactory ;
public ParserClient(Map<String, Parser> parserMapFactory) {
this.parserMapFactory = parserMapFactory;
}
/**
* 解析文件
* @param contentType 解析器类型
* @param filePath 文档路径
* @return
*/
public String parse(ContentTypeEnum contentType,String filePath) {
return parserMapFactory
.get(contentType.getParserName())
.parse(filePath);
}
}
5、单元测试
@Autowired
private ParserClient parserClient;
@Test
public void test7(){
System.out.println(parserClient.parse(ContentTypeEnum.WORD,"D:/xxxx.docx"));
}
打印结果:
wordParser
6、服务定位器模式
另外工厂接口,还可以通过服务定位来声明【Service Locator Pattern】
//定义工厂接口
public interface ParserFactory {
Parser getParser(ContentType contentType);
}
// 配置工厂bean
@Configuration
public class ParserConfig {
@Bean("parserFactory")
public FactoryBean serviceLocatorFactoryBean() {
ServiceLocatorFactoryBean factoryBean = new ServiceLocatorFactoryBean();
// 设置服务定位接口
factoryBean.setServiceLocatorInterface(ParserFactory.class);
return factoryBean;
}
}
作者:JAVA旭阳
链接:https://juejin.cn/post/7186464211868844093
//客户端使用,有点差异
@Service
public class Client {
private final ParserFactory parserFactory;
@Autowired
public Client(ParserFactory parserFactory) {
this.parserFactory = parserFactory;
}
public List getAll(ContentTypeEnum contentType) {
..
// 关键点,直接根据类型获取
return parserFactory
.getParser(contentType)
.parse("xxxxxxpath");
}
..
}
作者:JAVA旭阳
链接:https://juejin.cn/post/7186464211868844093
来源:稀土掘金
小结
策略模式:简单使用,扩展添加新的解析器(功能)就行,再也不用修改客户端了,满足开闭原则。