两个工厂类,以产生不同的接口实例具有相同condtion
问题描述:
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设计,请帮助我
答
不,您目前的设计是不正确的。
您的代码显然是违反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;
}
}
我不希望共享的映射器实现对系统 重用解析器。
Parsing
和Mapping
责任应该由自己的类来处理(如XMLParser
,XMLMapper
,JSonParser
,等..),如下图所示,那么这将遵守对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();
}
}
您的命名完全违反Java约定。类总是**是'PascalCase'; 'camelCase'被保留给变量。 'UPPER_SNAKE_CASE'是为编译时间常量保留的。请相应地更新您的代码。 –
至于实际问题;我建议你用'getParser'和'getMapper'方法创建一个'接口ParserMapper'或类似的接口。让你的工厂返回一个“ParserMapper” - 这是除非有任何理由使用带'JsonParser'的'XmlMapper'。 –
@BoristheSpider你是对的,但想法是解析器本身将被其他模块重用,所以我分离了两个。 – sujin