概念
定义一个用于创建对象的接口,但是让子类决定实例化哪一个类,让一个类的实例化延迟到子类中。
实例
单听概念或许有点笼统,但对于不了解设计模式的程序猿,其实在很多情况下已经使用过该设计模式。我们常用的框架中,就会使用到该设计模式,简单的例子比如我们框架常有的日志模块,我们对于日志写入的适配,就已经使用到了。大多情况下框架的日志默认大多写到文件或者数据库中,但这并不适用于我们实际开发体验,当我们系统中出现错误时,很显然,这种方式很难定位排查到指定的位置,这是我们不妨把日志写入到elasticsearch,高速的检索方式,会在我们日常系统维护之中起到非常大的作用。
下面我们将用一个简单的日志记录去解释工厂方法模式的实际应用:
- Logger 日志记录接口
public interface Logger {
public void writeLog();
}
抽象工厂集合了我们适配日志时需要实现的接口,这里我们只简单处理。
2. FIleLogger 文件日志记录器
public class FileLogger implements Logger {
public void writeLog() {
System.out.printkn("文件日志记录");
}
}
- DatabaseLogger 数据库日志记录器
public class DatabaseLogger implements Logger {
public void writeLog() {
System.out.printkn("数据库日志记录");
}
}
- EsLogger elasticsearch日志记录器
public class EsLogger implements Logger {
public void writeLog() {
System.out.printkn("Elasticsearch日志记录");
}
}
- LoggerFactory 日志记录器工厂接口
public interface LoggerFactory {
public Logger createLogger();//抽象工厂方法
}
- EsLoggerFactory elasticsearch日志记录器工厂类
public class EsLoggerFactory implements LoggerFactory {
public function createLogger() {
Logger logger = new EsLogger();
return logger;
}
}
- DatabaseLoggerFactory 数据库日志记录器工厂类
public class DatabaseLoggerFactory implements LoggerFactory {
public function createLogger() {
Logger logger = new DatabaseLogger();
return logger;
}
}
文件日志记录器工厂类也是同样的道理,这里我们直接省略。
- Client 测试使用
public class Client {
public static void main(String args[]) {
LogggerFactory factory;
Logger logger;
factory = new EsLoggerFactory();
//factory = new DatabaseFactory();
loggger = factory.createLogger();
logger.writeLog();
}
}
通过了解以上实例,我们再来分析一下工厂方法结构:
- 抽象产品(Product):定义产品使用的接口,产品实例需实现它的方法,例如上例的Logger接口。
- 具体产品(ConcreteProduct):实现抽象产品的接口,例如上面的FileLogger、DatabaseLogger、EsLogger。
- 抽象工厂(Factory):声明抽象工厂方法,例如上例的Factory中的createLogger方法,即为抽象工厂方法。
- 具体工厂(ConcreteFactory):抽象工厂类的子类,实现抽象工厂方法,返回具体的产品实例。
以上就是工厂方法模式的解释以及其结构。
缺点
- 每添加一个具体的产品就必须增加一个类,增加复杂性,编译和运行会给系统带来额外的开销。
- 由于考虑扩展性,客户端使用抽象层定义,增加系统的理解难度。
优点
- 扩展性好,符合开闭原则
适用环境
- 扩展性比较强的业务。
- 客户端并不关心使用的对象类是哪个。
上期答案
D
一问三不知
以下关于工厂方法模式的叙述错误的是()。
A. 在工厂方法模式中引入了抽象工厂类,而具体产品的创建延迟到具体工厂中实现
B. 工厂方法模式添加新的产品对象很容易,无需对原有系统进行修改,符合开闭原则
C. 工厂方法模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态,工厂方法模式退化后可演变成抽象工厂模式
D. 工厂方法模式中存在的问题是在添加新产品时需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,随着类个数的增加会给系统带来一些额外的开销