2017-04-08 97 views
0

Java程序两个工厂类,以产生不同的接口实例具有相同condtion

enum FILE_TYPE { 
    XML, JSON; 
} 

interface Parser { 
    void parse(); 
} 
class XMLparser implements Parser { 
    public void parse() { } 
} 
class JSONparser implements Parser { 
    public void parse() { } 
} 

interface Mapper { 
    void map(); 
} 
class XMLmapper implements Mapper { 
    public void map() { } 
} 
class JSONmapper implements Mapper { 
    public void map() { } 
} 

class ParserFactory { 
    public static Parser getInstance(FILE_TYPE fileType) { 
     switch(fileType) { 
     case XML: 
      return new XMLparser(); 
     case JSON: 
      return new JSONparser(); 
     } 
     return null; 
    } 
} 

class MapperFactory { 
    public static Mapper getInstance(FILE_TYPE fileType) { 
     switch(fileType) { 
     case XML: 
      return new XMLmapper(); 
     case JSON: 
      return new JSONmapper(); 
     } 
     return null; 
    } 
} 

在上面的Java程序都factory方法产生不同的接口实例这里依赖于相同的条件下,I,E都使用相同的枚举FILE_TYPE。

对这种情况使用两种工厂方法是否正确?约束是我无法将两个界面合并为一个。

我很新来java设计,请帮助我

+1

您的命名完全违反Java约定。类总是**是'PascalCase'; 'camelCase'被保留给变量。 'UPPER_SNAKE_CASE'是为编译时间常量保留的。请相应地更新您的代码。 –

+1

至于实际问题;我建议你用'getParser'和'getMapper'方法创建一个'接口ParserMapper'或类似的接口。让你的工厂返回一个“ParserMapper” - 这是除非有任何理由使用带'JsonParser'的'XmlMapper'。 –

+0

@BoristheSpider你是对的,但想法是解析器本身将被其他模块重用,所以我分离了两个。 – sujin

回答

2

不,您目前的设计是不正确的。

您的代码显然是违反open closed principle也就是说,你将最终switch语句在太多的地方,这不是一个好的设计,因为如果你想添加HTML解析器(或其他一些分析器后)您需要将switch语句添加到两个Factory类中。

解决的办法是,你需要使用抽象工厂模式,如下图所示:

interface ContentHandler { 
    public void parse(); 
    public void map(); 
} 


public class XMLContentHandler implements ContentHandler { 

    public void parse() { } 

    public void map() { } 
} 


public class JSONContentHandler implements ContentHandler { 

    public void parse() { } 

    public void map() { } 
} 

class ContentFactory { 
    public static ContentHandler getInstance(FILE_TYPE fileType) { 
     switch(fileType) { 
     case XML: 
      return new XMLContentHandler(); 
     case JSON: 
      return new JSONContentHandler(); 
     } 
     return null; 
    } 
} 

我不希望共享的映射器实现对系统 重用解析器。

ParsingMapping责任应该由自己的类来处理(如XMLParserXMLMapperJSonParser,等..),如下图所示,那么这将遵守对single responsibility原则。

public class XMLContentHandler implements ContentHandler { 

     @Inject 
     private XMLParser xmlParser; 

     @Inject 
     private XMLMapper xmlMapper; 


     public void parse() { 
      xmlParser.parse(); 
     } 

     public void map() { 
      xmlMapper.map(); 
     } 
} 
+0

感谢您的回答。在这个解析器中将被系统中的其他模块重用。映射器的实现将是非常巨大的,所以我不想将映射器实现分享给重用解析器的系统。 – sujin

+0

我建议在上面的'XMLHandler'中注入'XMLMapperImpl'和'XMLParserImpl',并且责任是分开的。同样对于JSon – developer

+0

我是一个非常新的面向对象的新设计,能否请你给我一个小代码示例 – sujin

相关问题