基本内容
定义一个创建对象的工厂方法接口,让实现该接口的类来决定实例化的类。该模式将对象的创建逻辑封装在工厂方法中。
该模式解决了产品拓展问题,如果使用万能工厂(即简单工厂模式),随着产品的增多,则不便于维护,所以根据单一职责原则,我们进行了拆分,让一个类只有一个职能。例如Java课程由Java工厂创建,python由python工厂创建。
当然如果产品少而且没有什么新增需求,则使用简单工厂模式仍然是合适的,反而避免了过度设计。
与简单工厂模式的区别
简单工厂模式 把所有创建逻辑集中在一个类里,是由一个工厂类根据参数决定创建哪一个具体实现类的实例;
基本流程是:定义接口 + 不同实现类 + 工厂依赖接口 + 根据参数创建不同实现类对象
工厂方法模式 是将创建逻辑交给子类的工厂类,每个子类负责创建一个具体产品。符合单一职责原则,扩展性更好,可维护性也更好
不同适用场景
简单工厂模式 产品种类少、变化不频繁,快速开发
工厂方法模式 产品种类多、变化频繁,需要扩展性强
示例对比
简单工厂模式
// 产品接口
public interface Logger {
void log(String message);
}
// 具体产品A
public class ConsoleLogger implements Logger {
public void log(String message) {
System.out.println("控制台日志: " + message);
}
}
// 具体产品B
public class FileLogger implements Logger {
public void log(String message) {
System.out.println("文件日志: " + message);
}
}
// 简单工厂类
public class LoggerFactory {
public static Logger getLogger(String type) {
if ("console".equals(type)) {
return new ConsoleLogger();
} else if ("file".equals(type)) {
return new FileLogger();
}
return null;
}
}
// 使用
Logger logger = LoggerFactory.getLogger("console");
logger.log("Hello");
如果再增加一个 DatabaseLogger,必须修改 LoggerFactory 类,不符合开闭原则。
工厂方法模式
// 产品接口
public interface Logger {
void log(String message);
}
// 产品实现
public class ConsoleLogger implements Logger {
public void log(String message) {
System.out.println("控制台日志: " + message);
}
}
public class FileLogger implements Logger {
public void log(String message) {
System.out.println("文件日志: " + message);
}
}
// 抽象工厂
public interface LoggerFactory {
Logger createLogger();
}
// 具体工厂
public class ConsoleLoggerFactory implements LoggerFactory {
public Logger createLogger() {
return new ConsoleLogger();
}
}
public class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
return new FileLogger();
}
}
// 使用
LoggerFactory factory = new ConsoleLoggerFactory();
Logger logger = factory.createLogger();
logger.log("Hello");
假设我们需要新增一个DatabaseLoggerFactory ,则不需要修改已有类,扩展性强,符合开闭原则。