代码实现:https://github.com/nateshao/design-demo/tree/main/JavaDesignPatterns/simplefactory
创建型模式(Creational Pattern)
画图软件:https://app.diagrams.net
模式名称 | 定 义 |
---|---|
简单工厂模式(Simple Factory Pattern) | 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。 |
工厂方法模式(Factory Method Pattern) | 定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。 |
抽象工厂模式(Abstract Factory Pattern) | 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。 |
建造者模式(Builder Pattern) | 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。 |
原型模式(Prototype Pattern) | 使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。 |
单例模式(Singleton Pattern) | 确保一个类只有一个实例,并提供一个全局访问点来访问这个唯一实例。 |
具体产品类:将需要创建的各种不同产品对象的相关代码封装到具体产品类中
抽象产品类:将具体产品类公共的代码进行抽象和提取后封装在一个抽象产品类中
工厂类:提供一个工厂类用于创建各种产品,在工厂类中提供一个创建产品的工厂方法,该方法可以根据所传入参数的不同创建不同的具体产品对象
**客户端:**只需调用工厂类的工厂方法并传入相应的参数即可得到一个产品对象
if(arg.equalsIgnoreCase("Apple")) {
return new Apple();
}
else if(arg.equalsIgnoreCase("Banana")) {
return new Banana();
}
else {
......
}
简单工厂模式 (Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。 在简单工厂模式中用于创建实例的方法通常是静态(static)方法,因此又被称为静态工厂方法(Static Factory Method)模式
要点:如果需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无须知道其创建细节
简单工厂模式结构:简单工厂模式包含以下3个角色:
// 典型的抽象产品类代码:
public abstract class Product {
//所有产品类的公共业务方法
public void methodSame() {
//公共方法的实现
}
//声明抽象业务方法
public abstract void methodDiff();
}
// 典型的具体产品类代码:
public class ConcreteProduct extends Product{
//实现业务方法
public void methodDiff() {
//业务方法的实现
}
}
public 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;
}
}
// 典型的客户端代码:
public class Client {
public static void main(String args[]) {
Product product;
product = Factory.getProduct("A"); //通过工厂类创建产品对象
product.methodSame();
product.methodDiff();
}
}
某软件公司要基于Java语言开发一套图表库,该图表库可以为应用系统提供多种不同外观的图表,例如柱状图(HistogramChart)、饼状图(PieChart)、折线图(LineChart)等。该软件公司图表库设计人员希望为应用系统开发人员提供一套灵活易用的图表库,通过设置不同的参数即可得到不同类型的图表,而且可以较为方便地对图表库进行扩展,以便能够在将来增加一些新类型的图表。 现使用简单工厂模式来设计该图表库。
实例类图
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("src//designpatterns//simplefactory//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;
}
}
}
Java语言创建对象的几种方式
public class LoginAction {
private UserDAO udao;
public LoginAction() {
udao = new JDBCUserDAO(); //创建对象
}
public String execute() {
//其他代码
udao.findUserById(); //使用对象
//其他代码
}
}
若改为HibernateUserDAO必须修改源代码,违背开闭原则
所以,引入工厂类UserDAOFactory
UserDAO
的某个子类的构造函数发生改变或者需要添加或移除不同的子类,只要维护UserDAOFactory
的代码,不会影响到LoginAction
UserDAO
的接口发生改变,例如添加、移除方法或改变方法名,只需要修改LoginAction
,不会给UserDAOFactory
带来任何影响两个类A和B之间的关系应该仅仅是A创建B或者是A使用B,而不能两种关系都有。将对象的创建和使用分离,使得系统更加符合单一职责原则,有利于对功能的复用和系统的维护。
将抽象产品类和工厂类合并,将静态工厂方法移至抽象产品类中
模式优点
模式缺点
模式适用环境