2017-04-08 100 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

相關問題