简单工厂模式扩展
前言
这里讲的简单工厂模式是使用xml配置文件来获取参数,关于简单工厂模式的基础请看上一篇文章。
在上一篇文章中,可以知道下面这行代码是将sign参数传入工厂类,从而创建具体产品对象。
Operator product = Factory.getOperator("+");
不难发现,这种方式下创建对象必须通过修改客户端代码中静态工厂方法的参数来更换具体产品对象,客户端代码需要重新编译,这对于客户端而言违反了开闭原则。
为了解决这个问题,使用下面这种常用方法,可以实现在不修改客户端代码的前提下让客户端能顾更换具体产品对象。
练习题目
根据下面的类图,建立Java项目Simplefactory,并在Main函数中测试简单工厂的使用。
派生类的构造函数可以为空,display函数只写一行输出语句,不同派生类有区别即可。
工厂类ChartFactory中getChart函数的实现:通过参数type进行判断,若为type==”Histogram”,则实例化一个HistogramChart的对象并返回;若为type==”Line”,则实例化一个LineChart的对象并返回;若为type==”Pie”,则实例化一个PieChart的对象并返回,否则返回空。
源代码
Simplefactory.java
public class Simplefactory {
public static void main(String[] args) {
Chart chart;
String type = XMLUtil.getChartType();//获取config.xml文件里的type
chart = ChartFactory.getChart(type); //创建对应的chart对象
chart.display();//输出
}
}
ChartFactory.java
public class ChartFactory{
public static Chart getChart(String type) {
Chart product = null;
if (type.equals("Histogram")) {
product = new HistogramChart();
}
else if (type.equals("Line")) {
product = new LineChart();
}
else if (type.equals("Pie")) {
product = new PieChart();
}
return product;
}
}
Chart.java
public interface Chart{
public void display();
}
HistogramChart.java
public class HistogramChart implements Chart{
public HistogramChart() {}
@Override
public void display() {
System.out.println("这里是Histogram的输出");
}
}
LineChart.java
public class LineChart implements Chart{
public LineChart() {}
@Override
public void display() {
System.out.println("这里是Line的输出");
}
}
PieChart.java
public class PieChart implements Chart{
public PieChart() {}
@Override
public void display() {
System.out.println("这里是Pie的输出");
}
}
config.xml
<?xml version="1.0"?>
<config>
<chartType>Histogram</chartType>
</config>
XMLUtil.java
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;
public class XMLUtil {
public static String getChartType() {
//该方法用于从XML配置文件中提取图表类型,并返回类型名
try {
//创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("src//project02//config.xml"));
//获取包含图表类型的文本结点
NodeList nl = doc.getElementsByTagName("chartType");
Node classNode = nl.item(0).getFirstChild();
String chartType = classNode.getNodeValue().trim();
return chartType;
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
return null;
}
}
}
结论
不难发现,在上述客户端代码中不包含任何与具体图表对象相关的信息,如果需要更换具体图表对象,只需修改配置文件config.xml,无须修改任何源代码,符合开闭原则。
本篇文章参考书籍有:
《Java设计模式》 刘伟——清华大学出版社,2018
作者:阿涛
CSDN博客主页:https://blog.csdn.net/qq_43313113
如有不对的地方,欢迎在评论区指正
欢迎大家关注我,我将持续更新更多的文章