案例介绍
有这样一个场景,一个公司通过XML格式数据与客户通信,他们从客户那里接受订单,订单中发生的错误,上一个订单的反馈,以及对订单的响应信息等都是通过XML格式数据,而且每种通信是不同的XML 格式数据。公司想开发一个应用来完成XML的解析和显示。
如果你来研发此应用,你该去如何设计开发呢?首先仔细分析下上面的需求,核心需求是不同的XML格式数据需要不同的解释器,但是处理这些格式的数据的主逻辑都是一样的,从XML数据获取信息然后显示信息。
分析完需求后,你可能需要一个工厂生产XML 解析器,而且是在运行时根据XML的格式类型来动态创建,这种场景正适合工厂方法模式,定义一个方法创建对象,但具体的创建工作由具体的子类来创建。
工厂方法模式详解
工厂方法模式提供了一种方式来封装具体类型的实例化逻辑。工厂方法模式封装了必须的功能,但是获取具体实例的方法由子类继承重写来提供,避免了需要提供单独的方法根据条件来获取具体类的实例,具体类图如下:
** Product**
定义产品的接口,工厂方法的返回类型
Creator
- 声明一个工厂方法,返回 Product, 可以提供一个默认的实现
工厂方法代码实现
具体实现类图如下:
public interface XmlParser {
String parser();
}
public class OrderXmlParser implements XmlParser{
@Override
public String parser() {
System.out.println("Parser Order xml...");
return "Order XML Message";
}
}
public class FeedbackXmlParser implements XmlParser{
@Override
public String parser() {
System.out.println("Parser Feedback xml...");
return "Feedback XML Message";
}
}
public class ErrorXmlParser implements XmlParser {
@Override
public String parser() {
System.out.println("Parser Error Xml...");
return "Error XML Message";
}
}
public class ResponseXmlParser implements XmlParser {
@Override
public String parser() {
System.out.println("Parser Response xml...");
return "Response XML Message";
}
}
public abstract class DisplayService {
public void display() {
XmlParser xmlParser = getXmlParser();
String message = xmlParser.parser();
System.out.println(message);
}
protected abstract XmlParser getXmlParser();
}
public class ErrorXmlDisplayService extends DisplayService {
@Override
protected XmlParser getXmlParser() {
return new ErrorXmlParser();
}
}
public class FeedbackXmlDisplayService extends DisplayService{
@Override
protected XmlParser getXmlParser() {
return new FeedbackXmlParser();
}
}
public class OrderXmlDisplayService extends DisplayService {
@Override
protected XmlParser getXmlParser() {
return new OrderXmlParser();
}
}
public class ResponseXmlDisplayService extends DisplayService {
@Override
protected XmlParser getXmlParser() {
return new ResponseXmlParser();
}
}
public class TestFactoryMethodPattern {
public static void main(String[] args) {
DisplayService displayService = new FeedbackXmlDisplayService();
displayService.display();
displayService = new OrderXmlDisplayService();
displayService.display();
displayService = new ErrorXmlDisplayService();
displayService.display();
displayService = new ResponseXmlDisplayService();
displayService.display();
}
}
工厂方法模式的使用场景
当遇如下场景时可考虑工厂方法模式
- 一个类无法预料它场景的对象的具体类时
- 一个类想让它的子类创建具体对象时
- 类一部分职责委托给子类,只有子类才知道具体的信息或条件
JDK 中的工厂方法模式应用
- java.util.Calendar#getInstance()
- java.util.ResourceBundle#getBundle()
- java.text.NumberFormat#getInstance()
- java.nio.charset.Charset#forName()
- java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (Returns singleton object per protocol)
下载源码链接