创建型模式-简单工厂模式
一、入门
由于创建实例的方法是静态方法,因此又叫静态工厂方法
- 定义:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。
- 要点:需要什么,传入一个正确的参数即可获取所需对象,无需知道创建细节。
二. 角色
- Factory(工厂角色):工厂类,简单工厂模式的核心,在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product
- Product(抽象产品角色):工厂类所创建的所有对象的父类,封装了各种产品对象的公有方法
- ConcreteProduct(具体产品角色):简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法。
三、典型的抽象产品类代码
- 产品抽象类
abstract class Product {
//所有产品类的公共业务方法
public void methodSame() {
//公共方法的实现
}
//声明抽象业务方法
public abstract void methodDiff();
}
- 具体的产品类
class ConcreteProduct extends Product {
//实现业务方法
public void methodDiff() {
//业务方法的实现
}
}
class ConcreteProductOther extends Product {
//实现业务方法
public void methodDiff() {
//业务方法的实现
}
}
- 工厂类
当增加实现类,得该源码,不符合开闭原则,需要优化
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;
}
}
- 客户端代码
class Client {
public static void main(String args[]) {
Chart chart;
String type = XMLUtil.getChartType(); //读取配置文件中的参数
chart = ChartFactory.getChart(type); //创建产品对象
chart.display();
}
}
- 配置类
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.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.getElementsByTagName("chartType");
Node classNode = nl.item(0).getFirstChild();
String chartType = classNode.getNodeValue().trim();
return chartType;
}
catch(Exception e) {
e.printStackTrace();
return null;
}
}
}
- 配置文件
<?xml version="1.0"?>
<config>
<chartType>histogram</chartType>
</config>
四、简单工厂模式的简化
将抽象产品类和工厂类合并,将静态工厂方法移至抽象产品类中
五、简单工厂模式的优缺点
1). 优点
- 对象创建和实用的分离
- 创建对象配置即可,无需记住需要创建实例的全类名,对开发者友好。
- 实现了一定程度的开闭原则
2). 缺点
- 工厂类集中了所有产品的创建逻辑,职责过重,一旦不能正常工作,整个系统都要受到影响。
- 增加了系统中类的个数,系统复杂性和理解难度提高。
- 系统拓展困难,一旦添加新的产品,不得不改源码,违反了开闭原则,不利于系统的拓展和维护。
- 简单工厂模式使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构。
六、简单工厂模式的适用场景
- 工厂类负责创建的对象比较少,由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象并不关心。