【问题标题】:Need suggestion on Parser Design Strategy [closed]需要有关解析器设计策略的建议 [关闭]
【发布时间】:2015-09-21 07:07:54
【问题描述】:

我需要关于解析器设计策略的建议

考虑type1, type2, type3 是三个不同格式的不同csv 文件,它们将分别被Parser1, Parser2, Parser3 解析。
将来,这将演变为解析来自其他来源(如 dbs)的信息。
还会有新的解析器出现。设计解析器的最佳方法是什么? factory/ abstract factory 是一个好的候选人吗?
一些好处和例子会有帮助吗?

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 框架。当我需要使用时会有什么好处和影响?

【问题讨论】:

  • 我投票结束这个问题,因为这个问题属于Programmers Stack Exchange
  • @Seelenvirtuose 这个问题不适合程序员——它会很快被否决并在那里关闭,请参阅meta.programmers.stackexchange.com/questions/6483/… 推荐阅读:What goes on Programmers.SE? A guide for Stack Overflow
  • @gnat 关于去哪里的决定似乎真的很复杂。因为我很少浏览程序员,所以我首先阅读了他们的help page on being on-topic。阅读“关于软件开发的概念性问题”、“软件架构和设计”以及“算法和数据结构概念”——此外,it is not about 部分没有被击中,我得出结论这似乎是这个地方。请告诉我我哪里出错了,这个问题属于什么地方。
  • @gnat 此外,OP 在那里问了这个问题并得到了投票(并回答)!
  • @Seelenvirtuose 这个问题可能程序员的话题,这不是问题。问题是,无论它在哪里成为话题,这都不是一个很好的问题,因为它太宽泛了。我不知道为什么这个 PSE 交叉帖子得到了赞成。

标签: java parsing dependency-injection abstract-factory


【解决方案1】:

1) 设计问题有个人解释/品味的空间,但总而言之,我非常喜欢您的方法,由于其灵活性和模块化,它在行业中很常见。 有时我可以不使用工厂的层次结构,但显然这取决于环境。

2) 你的“类 ParserFactory”有什么用?我没有看到它增加了灵活性/解耦,而不是旧的“new Parser1Factory("CSV").createParser()”......但也许你有一些我错过的可行设计意图。

3) 关于 DI,我主要可以向 Spring 作证——你的代码会很好地配合它。 DI 的重点是“好的,你知道如何创建解析器,现在如何将它们传递给业务代码”?例如。如果您有一些“银行服务”:

// 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 实例共同合作存在 ,每个都有不同的工厂类型......然后你会给框架单独的说明关于如何创建你的具体factori(es),例如"new Parser1Factory("CSV")。使用 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 的 FactoryBean 接口,尽管您实际上不必这样做:避免依赖框架的代码是一个合理的决定。

【讨论】:

  • 谢谢佩利特。关于您的“我的“类 ParserFactory”有什么用?在你现在指出我之后,我发现 ParserFactory 类没有真正的好处。我参考了抽象工厂设计模式。那么抽象工厂的真正用途是什么?你能给我一些现实生活中的案例吗?对我来说,Parser1Factory、Parser2factory 等……单个工厂就足够了。再次感谢您的详细回答。
  • 您好,关于您的特定 ParserFactory - 您看到的教程可能有一些我缺少的详细意图,但无论如何经典的 AbstractFactory 不需要它。它只需要一段代码,最终选择一些 concrete 工厂类型。一种工厂工厂(所以它类似于“getFactory”,它返回 newParser1Factory、newParser2Factory 等,无论您必须在它们之间决定什么逻辑)。
  • 对于AbstractFactory,它有点像英文解释。 AFAIK 最初的 GoF 强调了创建 相关 对象的 group 的具体挑战。例如。 UI 小部件(按钮、复选框、单选按钮...)必须与某个主题(全部为黄色或全部为蓝色)保持一致。解决方案:带有子类 YellowishFactory、BluishFactory... 的 AbstractFactory,然后是一些集中逻辑来选择工厂(一种工厂中的工厂),从而轻松切换主题
  • 现在你的代码不是经典的故事,因为它只是一个产品......但也许你仍然可以称它为保证所有解析器都是相同类型的私有案例。恕我直言,这是合法的,而且效果很好。但是有时(只是有时)当我只有 1 个产品 + 简单的需求时,我可能只满足于一个简单的工厂......而且如果需求变得复杂,我不害怕在未来进行重构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-30
相关资源
最近更新 更多