1.设计思想
首先将需要创建的各种不同对象的相关代码封装到不同的类中,这些类成为具体产品类,而将它们公共的代码进行抽象和提取后封装在一个抽象的产品类中,每一个具体产品类都是抽象产品类的子类;然后提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方式,该方法可以根据所传入的参数不同创建不同的具体产品对象;客户端只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象。
2.定义
简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。因为在简单工厂模式中用于创建实例的方法是静态方法,因此简单工厂模式又被成为静态工厂方法模式,它属于类创建型模式。
3.图表类设计
(1)抽象产品类
// 抽象产品类
abstract class Product {
public void methodSame() {
// 公共方法的实现
}
// 声明抽象业务方法
public abstract void methodDiff();
}
(2)工厂类
// 工厂类
class Factory {
// 静态工厂方法
public static Product getProduct(String arg) {
Product product = null;
if (arg.equalsIgnoreCase("A")) {
product = new ConcreteProductA();
// 初始化设置product
} else if (arg.equalsIgnoreCase("B")) {
product = new ConcreteProductB();
// 初始化设置product
}
return product;
}
};
(3)客户端代码
// 客户端代码
class Client {
public static void main(String args[]) {
Product product;
product = Factory.getProduct("A");// 通过工厂类创建产品对象
product.methodSame();
product.methodDiff();
}
};
4.图表库的解决方案
(1)结构图
(2)完整代码
c++: 抽象类作为父类->继承父类的子类->工厂类即测试的方法
// 抽象图表接口:抽象产品类
interface Chart {
public void display();
}
// 柱状图类:具体产品类
class HistogramChart implements Chart {
public HistogramChart() {
System.out.println("创建柱状图");
}
public void display() {
System.out.println("显示柱状图");
}
}
// 饼状图类:具体产品类
class PieChart implements Chart {
public PieChart() {
System.out.println("创建饼状图");
}
public void display() {
System.out.println("显示饼状图");
}
}
// 折线图类:具体产品类
class LineChart implements Chart {
public LineChart() {
System.out.println("创建折线图");
}
public void display() {
System.out.println("显示折线图");
}
}
// 图表工厂类:工厂类
class ChartFactory {
// 静态工厂方法
public static Chart getChart(String type) {
Chart chart = null;
if (type.equalsIgnoreCase("Histogram")) {
chart = new HistogramChart();
System.out.println("初始化设置柱状图");
} else if (type.equalsIgnoreCase("pie")) {
chart = new PieChart();
System.out.println("初始化设置饼状图");
} else if (type.equalsIgnoreCase("line")) {
chart = new LineChart();
System.out.println("初始化设置折线图");
}
return chart;
}
}
// 客户端代码
class Clent {
public static void main(String args[]) {
Chart chart;
chart = ChartFactory.getChart("histogram"); // 通过静态工厂方法创建产品
chart.display;
}
}
4.改进
为了能够在不更改客户端代码的情况下更换具体产品对象,可以将静态工厂方法的参数存储在XML或properties格式的配置文件中
import javax.xml.parsers.*;
import org.w3c.dom.*;
import ort.xml.sax.SAXException;
import java.io.*;
public class XMLUtil {
// 该方法用于从XML配置文件中提取图表类型,并返回类型名
public static String getChartType() {
try {
// 创建文档对象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("config.xml"));
// 获取包含图表类型的文本节点
NodeList nl = doc.getElementByTagName("ChartType");
Node classNode = nl.item(0).getFirstChild();
String chartType = classNode.getNodeValue().trim();
return chartType;
} catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
// 客户端代码
class Client {
public static void main(String args[]) {
Chart chart;
String type = XMLUtil.getChartType(); // 读取配置文件中的参数
chart = ChartFactory.getChart(type);
chart.display();
}
};
5.简单工厂模式的主要缺点
(1)一旦不能正常工作,整个系统都要受影响
(2)增加系统中类的个数,增减了系统的复杂度和理解难度
(3)不利于系统的扩展和维护
(4)使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构
6.适用场景
(1)工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法的业务逻辑过于复杂
(2)客户端只知道传入工厂类的采纳数,对于如何创建对象并不关心