一、概念
定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类
二、工厂方法模式结构
一共四个角色
1)Product(抽象产品):他是定义产品的接口,是工厂方法模式所创建对象的超类型,也就是产品对象的公共父类
2)ConcreteProduct(具体产品):它实现了抽象产品接口,某种类型的具体产品由专门的具有工厂创建,具体工厂和具体产品之间一一对应。
3)Factory(抽象工厂):在抽象工厂类中声明了工厂方法(Factory Method),用于返回一个产品。抽象工厂是工厂方法模式的核心,所有创建对象的工厂类都必须实现金额口
4)ConcreteFactory(具体工厂):它是抽象工厂类的子类,实现了在抽象工厂中声明的工厂方法,并可由客户端调用,返回一个具体产品类的实例,
三、工厂方法模式应用实例
其系统运行日志记录器(Lozzer)可以通过多种途径保存系统的运行日志,例如通过文件记录或数据库记录,用户可以通过修改配置文件灵活地更换日志记录方式。在设计各类日志记录器时,开发人员发现需要对日志记录器进行一些初始化工作,初始化参数的设置过程较为复杂,而且某些参数的设置有严格的先后次序,否则可能会发生记录失败。
为了更好地封装记录器的初始化过程并保证多种记录器切换的灵活性,现使用工厂方法模式设计该系统(注:在Java中常用的日志记录工具有 SLF4J、Log4j、GCLogViewer、Logstash 等)。
代码
1)Logger:日志记录器接口,充当抽象产品角色
//designpatterns.factorymethod.Logger.java
package designpatterns.factorymethod;
public interface Logger{
public void writeLog();
}
2)DatabaseLogger:数据库日志记录器,充当具体产品角色
//designpatterns.factorymethod.DatabaseLogger.java
package designpatterns.factorymethod;
public class DatabaseLogger implements Logger{
public void writeLog(){
System.out.println("数据库日志记录:");
}
}
3)FileLogger:文件日志记录器,充当具体产品角色
//designpatterns.factorymethod.FileLogger.java
package designpatterns.factorymethod;
public class FileLoggerimplements Logger{
public void writeLog(){
System.out.println("文件日志记录:");
}
}
4)LoggerFactory:日志记录器工厂接口,充当抽象工厂角色
// //designpatterns.factorymethod.LoggerFactory.java
package designpatterns.factorymethod;
public interface LoggerFactory{
public Logger createLogger();//抽象工厂方法
}
5)DatabaseLoggerFactory:数据库日志记录器工厂类,充当具体工厂角色
// //designpatterns.factorymethod.DatabaseLoggerFactory.java
package designpatterns.factorymethod;
public class DatabaseLoggerFactory implements LoggerFactory{
public Logger createLogger(){
//链接数据库,代码省略
//创建数据库日志记录器对象
Logger logger = new DatabaseLogger();
//初始化数据库日志记录器,代码省略
return logger;
}
}
6)FileLoggerFactory:文件日志记录器工厂类,充当具体工厂角色
//designpatterns.factorymethod.FileLoggerFactory.java
package designpatterns.factorymethod;
public class FileLoggerFactoryimplements LoggerFactory{
public Logger createLogger(){
//链接数据库,代码省略
//创建数据库日志记录器对象
Logger logger = new FileLogger();
//初始化数据库日志记录器,代码省略
return logger;
}
}
7) Client: 客户端测试类
//designpatterns.factorymethod.Client.java
package designpatterns.factorymethod;
public class Client{
public static void main(String [] args){
LoggerFactory factory = new FileLoggerFactory();//可引入配置文件和反射机制实现
Logger logger = factory.createLogger();
logger.writeLog();
}
}
四、反射机制于配置文件
1.Java反射机制
Java反射是指在程序运行时获取已知名称的类或已有对象的相关信息的一种机制,包括类的方法、属性、父类等信息,还包括实例的创建和实例类型的判断等,
本质是jvm得到class对象之后,再通过class对象进行反编译,从而获取对象的各种信息
2、配置文件
同上一个文章的配置文件
五、工厂方法模式优缺点与使用环境
工厂方法模式是简单工厂模式的延伸,它继承了简单工厂模式的优点,同时还弥补了简单工厂模式的不足。工厂方法模式是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。
1)优点
1)在工厂方法模式中,工厂方法用来创建客户所需的茶农,同时还向客户隐瞒了那种具体产品类将被实例化这一细节,用户只需要关系所需产品对应的工厂,无需关心创建细节,甚至无需知道具体产品类的类名
2)基于工厂角色和产品角色的多态性设计是工厂方法模式的关键
3)使用工厂方法模式的另一个优点实在系统中加入新产品时无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,符合开闭原则
2)缺点
1)在添加新产品时需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,由更多的类需要编译和运行,会给系统带来一些额外的开销
2)由于考虑到系统的可扩展性,需要引入抽象层进行定义,增加了系统的抽象性和理解难度。
3)适用环境
1)客户端不知道它所需要的对象的类
2)抽象工厂类通过其子类来指定创建那个对象。