需要有关解析器设计策略的建议
Need suggestion on Parser Design Strategy
我需要有关解析器设计策略的建议
考虑 type1, type2, type3
是三个不同的 csv 文件,它们具有不同的格式,将分别由 Parser1, Parser2, Parser3
解析。
将来这将演变为解析来自其他来源(如 dbs)的信息。
还将有新的解析器出现。设计解析器的最佳方法是什么? factory
/abstract
工厂是合适的候选人吗?
一些好处和例子会有所帮助吗?
Type1 - Parser1
Type2 - Parser2
Type3 - Parser3
我已经放下我的代码,寻找宝贵的建议。
interface Parser<T>{
public List<T> parse (string s);
}
//where T - data model
class Parser1CSV implements Parser<Model1>{
//implement
//s-csv file
public List<Model1> parse (string s){
}
}
class Parser1DB implements Parser<Model1>{
//implement
//s- connection string
public List<Model1> parse (string s){
}
}
class Parser2CSV implements Parser<Model2>{
//implement
//s-csv file
public List<Model2> parse (string s){
}
}
//same way other parsers are implemented
interface AbstarctFactory<T>{
public Parser<T> createParser();
}
class Parser1Factory implements AbstarctFactory<Model1>{
private String type;
Parser1Factory(String type){
this.type = type;
}
public Parser<Model1> createParser(){
if(type.equals("CSV"){
return new Parser1CSV();
}else if(type.equals("DB"){
return Parser1DB();
}else{
throw UnSupportedOperationException("Not Supported.");
}
}
}
//same way other parser factories are implemented
class ParserFactory{
public static <T> Parser<T> getParser(AbstarctFactory<T> factory){
factory.createParser();
}
}
//Usage:
Parser<Model1> parser = ParserFactory.getParser(new Parser1Factory("CSV"));
List<Model1> list = parser.parse(file);
目前,我没有使用 DI 框架。当我需要使用时会有什么好处和影响?
1) 设计问题有个人空间interpretation/taste,但总而言之,我非常喜欢你的方法,由于其灵活性和模块化,它在行业中很常见。
有时我可以不用工厂的层次结构,但显然这会因情况而异。
2) 你的"class ParserFactory"有什么用?我没有看到它添加了 flexibility/decoupling,而不是旧的 "new Parser1Factory("CSV").createParser()"... 但也许您有一些我错过的可行设计意图。
3) 关于 DI,我主要可以证明 Spring - 你的代码会很好地配合它。 DI的点是"ok, you know how to create parsers, now how do you pass them on to the business code"?例如。如果你有一些 'BankService':
// Without DI:
public class BankService {
private AbstarctFactory factory= new Parser1Factory();
public void depositFundsFromFile(File file){
// use factory
}
}
// With DI:
public class BankService {
@Autowired
private AbstarctFactory factory; // will be injected by the framework
public void depositFundsFromFile(File file){
// use factory
}
}
=> DI 使 BankService 真正独立于具体工厂类型:BankService 不包含具体承诺 "new Parser1Factory",因此它可以与任何工厂一起工作,它甚至允许多个 BankService 实例 co-exist ,每个都有不同的工厂类型......然后你会给框架单独的说明关于如何创建你的具体工厂(es ) ,例如"new Parser1Factory("CSV")。对于 spring,此类单独的指令来自 XML 文件或@Configuration 代码。
4) 根据要求,DI 还可以注入解析器而不是工厂(同样,框架将需要单独的指令来创建解析器):
public class BankService ... {
@Autowired
private Parser parser; // will be injected from the framework
public void depositFundsFromFile(File file){
// use parser
}
}
5) 您可以考虑实现 Springs 的 FactoryBean 接口,尽管您确实不必这样做:避免依赖于框架的代码是一个合理的决定.
我需要有关解析器设计策略的建议
考虑 type1, type2, type3
是三个不同的 csv 文件,它们具有不同的格式,将分别由 Parser1, Parser2, Parser3
解析。
将来这将演变为解析来自其他来源(如 dbs)的信息。
还将有新的解析器出现。设计解析器的最佳方法是什么? factory
/abstract
工厂是合适的候选人吗?
一些好处和例子会有所帮助吗?
Type1 - Parser1
Type2 - Parser2
Type3 - Parser3
我已经放下我的代码,寻找宝贵的建议。
interface Parser<T>{
public List<T> parse (string s);
}
//where T - data model
class Parser1CSV implements Parser<Model1>{
//implement
//s-csv file
public List<Model1> parse (string s){
}
}
class Parser1DB implements Parser<Model1>{
//implement
//s- connection string
public List<Model1> parse (string s){
}
}
class Parser2CSV implements Parser<Model2>{
//implement
//s-csv file
public List<Model2> parse (string s){
}
}
//same way other parsers are implemented
interface AbstarctFactory<T>{
public Parser<T> createParser();
}
class Parser1Factory implements AbstarctFactory<Model1>{
private String type;
Parser1Factory(String type){
this.type = type;
}
public Parser<Model1> createParser(){
if(type.equals("CSV"){
return new Parser1CSV();
}else if(type.equals("DB"){
return Parser1DB();
}else{
throw UnSupportedOperationException("Not Supported.");
}
}
}
//same way other parser factories are implemented
class ParserFactory{
public static <T> Parser<T> getParser(AbstarctFactory<T> factory){
factory.createParser();
}
}
//Usage:
Parser<Model1> parser = ParserFactory.getParser(new Parser1Factory("CSV"));
List<Model1> list = parser.parse(file);
目前,我没有使用 DI 框架。当我需要使用时会有什么好处和影响?
1) 设计问题有个人空间interpretation/taste,但总而言之,我非常喜欢你的方法,由于其灵活性和模块化,它在行业中很常见。 有时我可以不用工厂的层次结构,但显然这会因情况而异。
2) 你的"class ParserFactory"有什么用?我没有看到它添加了 flexibility/decoupling,而不是旧的 "new Parser1Factory("CSV").createParser()"... 但也许您有一些我错过的可行设计意图。
3) 关于 DI,我主要可以证明 Spring - 你的代码会很好地配合它。 DI的点是"ok, you know how to create parsers, now how do you pass them on to the business code"?例如。如果你有一些 'BankService':
// Without DI:
public class BankService {
private AbstarctFactory factory= new Parser1Factory();
public void depositFundsFromFile(File file){
// use factory
}
}
// With DI:
public class BankService {
@Autowired
private AbstarctFactory factory; // will be injected by the framework
public void depositFundsFromFile(File file){
// use factory
}
}
=> DI 使 BankService 真正独立于具体工厂类型:BankService 不包含具体承诺 "new Parser1Factory",因此它可以与任何工厂一起工作,它甚至允许多个 BankService 实例 co-exist ,每个都有不同的工厂类型......然后你会给框架单独的说明关于如何创建你的具体工厂(es ) ,例如"new Parser1Factory("CSV")。对于 spring,此类单独的指令来自 XML 文件或@Configuration 代码。
4) 根据要求,DI 还可以注入解析器而不是工厂(同样,框架将需要单独的指令来创建解析器):
public class BankService ... {
@Autowired
private Parser parser; // will be injected from the framework
public void depositFundsFromFile(File file){
// use parser
}
}
5) 您可以考虑实现 Springs 的 FactoryBean 接口,尽管您确实不必这样做:避免依赖于框架的代码是一个合理的决定.