工厂模式
创建型模式
访问次数: 26
工厂模式定义了一个创建对象的接口,但让子类决定实例化哪个类。工厂方法让类的实例化推迟到子类。
视频教程
类图
classDiagram
class Product {
<<interface>>
+operation()
}
class ConcreteProductA {
+operation()
}
class ConcreteProductB {
+operation()
}
class Creator {
<<abstract>>
+factoryMethod() Product
+someOperation()
}
class ConcreteCreatorA {
+factoryMethod() Product
}
class ConcreteCreatorB {
+factoryMethod() Product
}
Product <|-- ConcreteProductA
Product <|-- ConcreteProductB
Creator <|-- ConcreteCreatorA
Creator <|-- ConcreteCreatorB
ConcreteCreatorA --> ConcreteProductA
ConcreteCreatorB --> ConcreteProductB
源代码示例
// 产品接口
interface Product {
void operation();
}
// 具体产品A
class ConcreteProductA implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductA operation");
}
}
// 具体产品B
class ConcreteProductB implements Product {
@Override
public void operation() {
System.out.println("ConcreteProductB operation");
}
}
// 抽象创建者
abstract class Creator {
public abstract Product factoryMethod();
public void someOperation() {
Product product = factoryMethod();
product.operation();
}
}
// 具体创建者A
class ConcreteCreatorA extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
// 具体创建者B
class ConcreteCreatorB extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
# 产品接口(抽象基类)
from abc import ABC, abstractmethod
class Product(ABC):
@abstractmethod
def operation(self):
pass
# 具体产品A
class ConcreteProductA(Product):
def operation(self):
print("ConcreteProductA operation")
# 具体产品B
class ConcreteProductB(Product):
def operation(self):
print("ConcreteProductB operation")
# 抽象创建者
class Creator(ABC):
@abstractmethod
def factory_method(self):
pass
def some_operation(self):
product = self.factory_method()
product.operation()
# 具体创建者A
class ConcreteCreatorA(Creator):
def factory_method(self):
return ConcreteProductA()
# 具体创建者B
class ConcreteCreatorB(Creator):
def factory_method(self):
return ConcreteProductB()
# 使用示例
if __name__ == "__main__":
creator_a = ConcreteCreatorA()
creator_b = ConcreteCreatorB()
creator_a.some_operation()
creator_b.some_operation()
应用场景
当需要创建的对象类型在运行时确定,或者需要将对象创建与使用分离时。应用场景包括:
1)文档处理系统中,根据文件类型创建不同的解析器(PDF解析器、Word解析器、Excel解析器)
2)游戏开发中根据角色类型创建不同的角色对象(战士、法师、弓箭手)
3)消息队列系统中根据消息类型创建不同的消息处理器(邮件处理器、短信处理器、推送处理器)
4)电商系统中根据商品类型创建不同的商品展示组件(图书展示、服装展示、电子产品展示)
5)多媒体播放器中根据文件格式创建不同的解码器(MP3解码器、MP4解码器、AVI解码器)
精选场景详解 —— 文档处理:按文件类型创建解析器
问题背景
文档平台要支持 PDF、Word、Excel 等格式。若在业务里硬编码解析器类型,扩展新格式时会牵动多处调用代码,也难做到「解析器实现可替换」。
模式如何解决
选用工厂方法模式:定义抽象 Creator(DocumentParserCreator)声明 factoryMethod,由 ConcreteCreator(PdfParserCreator、WordParserCreator 等)决定实例化哪种解析器。
与简单工厂的区别:
- 简单工厂:一个工厂类用分支创建所有产品;
- 工厂方法:创建职责下沉到子类,符合开闭原则,扩展新格式时新增 Creator/Product,少改已有类。
客户端依赖 Creator 抽象,调用 someOperation/parse 流程,无需知道具体解析器类名。适合「产品种类会持续增加」的文档系统。
场景模型(角色映射)
将模式中的抽象角色映射到该业务领域的具体类:
classDiagram
class DocumentParser {
<<interface>>
+parse(path: String) Document
}
class PdfParser {
+parse(path: String) Document
}
class WordParser {
+parse(path: String) Document
}
class ExcelParser {
+parse(path: String) Document
}
class ParserCreator {
<<abstract>>
+factoryMethod() DocumentParser
+importFile(path: String) Document
}
class PdfParserCreator {
+factoryMethod() DocumentParser
}
class WordParserCreator {
+factoryMethod() DocumentParser
}
DocumentParser <|.. PdfParser
DocumentParser <|.. WordParser
DocumentParser <|.. ExcelParser
ParserCreator <|-- PdfParserCreator
ParserCreator <|-- WordParserCreator
PdfParserCreator --> PdfParser
WordParserCreator --> WordParser
ParserCreator --> DocumentParser