需要对Parser设计策略提出建议

时间:2015-09-21 07:07:55

标签: java parsing dependency-injection abstract-factory

我需要对解析器设计策略提出建议

考虑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 个答案:

答案 0 :(得分:0)

1)设计问题有个人口译/品味的空间,但总的来说我非常喜欢你的方法,由于其灵活性和行业特点,它在行业中很常见。模块化。 有时候我可以不使用工厂的层次结构,但显然会因环境而异。

2)你的&#34;类ParserFactory&#34 ;?的用途是什么?我没有看到它增加灵活性/脱钩,而不是好的旧的&#34;新的Parser1Factory(&#34; CSV&#34;)。createParser()&#34; ...但也许你我有一些可行的设计意图,我错过了。

3)关于DI,我主要可以证明Spring - 你的代码会很好地发挥它。 DI的重点是,#,你知道如何创建解析器,现在如何将它们传递给业务代码&#34;?例如。如果你有一些&#39; BankService&#39;:

// 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
   }
}

=&GT; DI使BankService真正独立于具体的工厂类型:BankService不包含具体的承诺&#34;新的Parser1Factory&#34;,所以它准备好与任何工厂合作,它甚至允许多个BankService实例共存,每个都有不同的工厂类型......然后,您将提供关于如何创建具体因素的框架单独说明 ,例如&#34;新的Parser1Factory(&#34; CSV&#34;)。对于spring,这些单独的指令来自XML文件或@Configuration代码。

4)根据要求,DI也可以注入Parser而不是工厂(同样,框架将需要单独的Parser创建指令):

public class BankService ... {
   @Autowired
   private Parser parser; // will be injected from the framework
   public void depositFundsFromFile(File file){
      //  use parser
   }
}

5)你可以考虑实施Springs&#39; FactoryBean接口,虽然你真的不必:它是避免框架相关代码的合法决定。