一、场景
服务类定义了一堆操作的抽象接口。具体的服务提供者实现这个接口。分离的服务定位器提供了通过查询获取服务方法,同时隐藏了服务提供者的具体细节和定位它的过程。
场景:根据文件类型,使用CSV解析器或者JSON解析器,在调用客户端的时候使用if else去做判断,例如:
if (type == 'CSV') {
//.. CSV解析
} else if (type == 'JSON') {
//.. JSON解析器处理
}
当我们新增一种类型时,就需要修改这里的代码去适配新的类型。
这种情况耦合程度太高。
此时我们可以使用服务定位模式去处理这种情况(原理是通过反射的方式,根据bean的name去获得对应的实现类,从而进行解析)
二、定义解析接口
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:30
* @Description: 解析器接口
*/
public interface Parser {
/**
* 解析
*
* @param reader reader
* @return {@link List}
*/
List parse(Reader reader);
}
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:31
* @Description: json解析器
*/
@Component("JSON")
@Log4j2
public class JsonParser implements Parser {
@Override
public List parse(Reader reader) {
log.info("JSON解析器");
return new ArrayList();
}
}
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:32
* @Description: csv解析器
*/
@Component("CSV")
@Log4j2
public class CsvParser implements Parser {
@Override
public List parse(Reader reader) {
log.info("CSV解析器");
return new ArrayList();
}
}
三、定义服务定位接口
根据类型获取解析器
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:35
* @Description: 服务定位模式,服务定位接口
*/
public interface ParseFactory {
/**
* 根据类型获取解析器
*
* @param contentType 类型
* @return {@link Parser}
*/
Parser getParser(ContentType contentType);
}
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:39
* @Description: 服务定位接口配置类
*/
@Configuration
public class ParserConfig {
@Bean("parserFactory")
public FactoryBean serviceLocatorFactoryBean() {
ServiceLocatorFactoryBean serviceLocatorFactoryBean = new ServiceLocatorFactoryBean();
// 设置服务定位接口
serviceLocatorFactoryBean.setServiceLocatorInterface(ParseFactory.class);
return serviceLocatorFactoryBean;
}
}
四、使用demo
1、首先根据类型获取解析器
2、调用解析的解析方法
思考:如果直接使用反射,是否可以省去服务定位接口与配置类?
/**
* @Author: huanghwh
* @Date: 2023/03/12 下午9:42
* @Description: 服务定位模式实现demo
*/
@RestController
@RequestMapping(("/locator"))
public class demo {
@Autowired
private ParseFactory parseFactory;
@GetMapping("/getAll")
public List getAll(ContentType contentType) {
Reader reader = null;
// 使用服务定位模式获取对应的解析器,执行解析
Parser parser = parseFactory.getParser(contentType);
List result = parser.parse(reader);
return result;
}
}