1. 定义
定义一个用于创建对象的接口,让子类决定哪一个类实例化,工厂方法模式让一个类的实例化延迟到其子类;工厂方法模式简称为工厂模式,又可称为虚拟构造器模式或多态工厂模式
2. 工厂方法模式结构图
3. 工厂方法模式角色分析
- Product(抽象产品):它是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类
- ConcreteProduct(具体产品):实现了抽象产品接口,某种类型的具体产品由专门的具体工厂创建,具体工厂和具体产品之间一一对应
- Factory(抽象工厂):在抽象工厂类中,声明了工厂方法(Factory Method),用于返回一个产品;抽象工厂可以是接口也可以是抽象类或具体类,声明工厂方法并未实现
- ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了抽象工厂中定义的工厂方法,由客户端调用,返回一个具体产品类的实例;具体工厂方法负责创建具体产品对象,还可以负责产品对象的初始化工作以及一些资源的配置;
4. 工厂方法模式案例
5. 日志记录器的设计方案
1) 结构图
2) 实现代码
interface Logger {
public void writeLog
}
//数据库日志记录器:具体产品
class DatabaseLogger implements Logger {
public void writeLog() {
System.out.println("数据库日志记录.");
}
}
//文件日志记录器:具体产品
class FileLogger implements Logger {
public void writeLog() {
System.out.println("文件日志记录");
}
}
//抽象工厂
interface LoggerFactory {
public Logger createLogger();
}
class DatabaseLoggerFactory implements LoggerFactory {
public Logger createLogger() {
Logger logger = new DatabaseLogger();
return logger;
}
}
//文件日志记录器工厂类:具体工厂
class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
Logger logger = new FileLogger();
return logger;
}
}
//客户端
class Client {
public static void mian(String args[]) {
LoggerFactory factory = new FileLoggerFactory();
logger = factory.createLogger();
logger.writeLog();
}
}
3) 重载的工厂方法
日志记录器的初始化方式可以有多种,如:为各种日志记录器提供默认实现;为数据库日志记录器提供数据库连接字符串;为文件日志记录器提供文件路径;将参数封装到一个Object类型的对象中,通过Object对象将配置参数传入工厂类;此时可以提供一组重载的工厂方法,以不同的方式对产品对象进行创建;对于同一个具体工厂而言,每个工厂方法创建的产品类型均要相同.
4) 工厂方法的隐藏
为进一步简化代码,在工厂类中将直接调用产品类的业务方法,客户端无须调用工厂方法创建产品,直接通过工厂即可使用创建的对象中的业务方法
代码修改
abstract class LoggerFactory{
//在工厂类中直接调用日志记录器类的业务方法
public void writeLog(){
Logger logger = this.createLogger();
logger.writeLog();
}
public abstract Logger createLogger();
}
class Client{
public static void main(String args[]){
LoggerFactory factory = (LoggerFactory)XMLUtil.getBean();
factory.writeLog();
}
}
6. 工厂方法模式总结
简单工厂模式中存在的严重问题: 当系统中需要引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,者必定要修改工厂类的源代码,违背开闭原则; 但是工厂方法模式弥补了这个缺点
1) 主要优点
- 向客户端隐藏了具体产品类创建细节,用户只需要关心所需产品对应的工厂,无须关心细节甚至无须知道具体产品的类的类名
- 基于工厂角色和产品角色的多态性设计能让工厂可以自主确定创建何种产品对象,而创建对象的细节完全封装在具体工厂内部
- 在系统总加入新产品时,无须修改抽象工厂和抽象产品以及客户端,只要添加一个具体工厂和具体产品即可
2) 适用场景
- 客户端不需要知道其所需的对象的类,
- 抽象工厂类通过其子类来指定创建哪个对象,在工厂方法模式中,抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象;