工厂模式
工厂模式就是为了简化具体对象的创建的细节;
工厂模式简化图
+------------------+
| Product |
+------------------+
| operation() |
+------------------+
^
|
|
+------------------------+------------------------+
| |
+---------------------+ +---------------------+
| ConcreteProductA | | ConcreteProductB |
+---------------------+ +---------------------+
| operation() | | operation() |
+---------------------+ +---------------------+
^ ^
| |
+-------------------------------------------------+
|
|
+------------------+
| Factory |
+------------------+
| createProduct() |
+------------------+
伪代码
- 定义协议(Protocol) :首先,定义一个协议,描述工厂所创建对象应该具有的属性和方法。
swift
Copy code
protocol Product {
func operation()
}
- 实现具体产品类:创建遵循协议的具体产品类。
swift
Copy code
class ConcreteProductA: Product {
func operation() {
print("ConcreteProductA operation")
}
}
class ConcreteProductB: Product {
func operation() {
print("ConcreteProductB operation")
}
}
- 实现工厂类:创建一个工厂类,负责实例化具体产品对象。
swift
Copy code
class Factory {
func createProduct(type: Int) -> Product {
switch type {
case 0:
return ConcreteProductA()
case 1:
return ConcreteProductB()
default:
fatalError("Invalid product type")
}
}
}
- 使用工厂创建对象:在需要创建对象的地方,通过工厂类创建对象实例。
swift
Copy code
let factory = Factory()
let productA = factory.createProduct(type: 0)
let productB = factory.createProduct(type: 1)
productA.operation() // 输出:ConcreteProductA operation
productB.operation() // 输出:ConcreteProductB operation
通过工厂模式,我们可以将对象的创建逻辑与客户端代码分离,使得客户端不需要关心具体对象的创建细节,从而提高了代码的灵活性和可维护性。
特殊场景-产品不遵守统一的协议
# 定义产品类1
class Product1:
def operation(self):
print("Product 1 operation")
# 定义产品类2
class Product2:
def operation(self):
print("Product 2 operation")
# 工厂类
class Factory:
def create_product(self, product_type):
if product_type == "Product1":
return Product1()
elif product_type == "Product2":
return Product2()
else:
raise ValueError("Invalid product type")
# 使用工厂创建产品并调用操作方法
factory = Factory()
product1 = factory.create_product("Product1")
product1.operation()
product2 = factory.create_product("Product2")
product2.operation()
高级用法-抽象工厂模式
伪代码
plaintext
Copy code
// 定义抽象工厂接口
interface AbstractFactory {
createProductA(): AbstractProductA
createProductB(): AbstractProductB
}
// 具体工厂类实现抽象工厂接口
class ConcreteFactory1 implements AbstractFactory {
createProductA(): AbstractProductA {
return new ConcreteProductA1()
}
createProductB(): AbstractProductB {
return new ConcreteProductB1()
}
}
class ConcreteFactory2 implements AbstractFactory {
createProductA(): AbstractProductA {
return new ConcreteProductA2()
}
createProductB(): AbstractProductB {
return new ConcreteProductB2()
}
}
// 定义抽象产品接口
interface AbstractProductA {
methodA(): void
}
interface AbstractProductB {
methodB(): void
}
// 具体产品类实现抽象产品接口
class ConcreteProductA1 implements AbstractProductA {
methodA(): void {
// 具体产品A1的方法实现
}
}
class ConcreteProductA2 implements AbstractProductA {
methodA(): void {
// 具体产品A2的方法实现
}
}
class ConcreteProductB1 implements AbstractProductB {
methodB(): void {
// 具体产品B1的方法实现
}
}
class ConcreteProductB2 implements AbstractProductB {
methodB(): void {
// 具体产品B2的方法实现
}
}
// 客户端代码使用抽象工厂和抽象产品
function clientCode(factory: AbstractFactory) {
let productA = factory.createProductA()
let productB = factory.createProductB()
// 使用产品A和产品B
productA.methodA()
productB.methodB()
}
// 使用具体工厂创建产品
let factory1 = new ConcreteFactory1()
clientCode(factory1)
let factory2 = new ConcreteFactory2()
clientCode(factory2)
在上面的示例中,抽象工厂接口定义了创建一组相关产品的方法。具体工厂类实现了抽象工厂接口,每个具体工厂负责创建一组具体产品。抽象产品接口定义了产品的通用方法,而具体产品类实现了具体的产品功能。客户端代码通过传入具体工厂对象来创建和使用一组相关产品。
举例:alamofire库执行器的设计
// 定义抽象请求协议
protocol Request {
// 发起请求的方法
func send() -> Response
}
// 定义具体请求对象
class URLRequest: Request {
func send() -> Response {
// 使用 URLSession 发起网络请求,并返回响应结果
}
}
// 定义抽象请求执行器协议
protocol SessionDelegate {
// 发起请求的方法,接收抽象请求对象,并返回响应结果
func sendRequest(request: Request) -> Response
}
// 定义具体的请求执行器
class URLSessionDelegate: SessionDelegate {
func sendRequest(request: Request) -> Response {
// 实现具体的网络请求逻辑,使用 URLRequest 发起网络请求,并返回响应结果
}
}
// 定义抽象工厂协议
protocol SessionFactory {
// 创建具体请求执行器的方法
func makeSessionDelegate() -> SessionDelegate
}
// 定义具体的工厂,用于创建 URLSessionDelegate
class URLSessionFactory: SessionFactory {
func makeSessionDelegate() -> SessionDelegate {
return URLSessionDelegate()
}
}
// 客户端代码使用抽象工厂创建请求执行器,并发送请求
class Client {
let sessionFactory: SessionFactory
init(factory: SessionFactory) {
self.sessionFactory = factory
}
func sendRequest() {
// 使用工厂创建请求执行器
let sessionDelegate = sessionFactory.makeSessionDelegate()
// 使用请求执行器发送请求
let request = URLRequest()
let response = sessionDelegate.sendRequest(request: request)
// 处理响应结果
// ...
}
}
// 使用 Alamofire 的示例
let urlSessionFactory = URLSessionFactory()
let client = Client(factory: urlSessionFactory)
client.sendRequest()
以上伪代码简要展示了Alamofire库中抽象工厂模式的实现思路。Alamofire通过抽象请求对象、抽象请求执行器和工厂接口的定义,实现了一种灵活的网络请求管理机制,使得用户可以轻松地定制和切换不同的网络请求执行器,而无需修改大量的客户端代码。
高级用法-工厂方法模式
伪代码
// 定义产品接口
interface Product {
method operation() -> void
}
// 具体产品类 A
class ConcreteProductA implements Product {
method operation() -> void {
// 实现具体产品 A 的操作
}
}
// 具体产品类 B
class ConcreteProductB implements Product {
method operation() -> void {
// 实现具体产品 B 的操作
}
}
// 定义工厂接口
interface Factory {
method createProduct() -> Product
}
// 具体工厂 A,用于创建产品 A
class ConcreteFactoryA implements Factory {
method createProduct() -> Product {
return new ConcreteProductA()
}
}
// 具体工厂 B,用于创建产品 B
class ConcreteFactoryB implements Factory {
method createProduct() -> Product {
return new ConcreteProductB()
}
}
// 客户端代码
class Client {
property factory: Factory
constructor(factory: Factory) {
this.factory = factory
}
method run() -> void {
// 使用工厂创建产品对象
product = factory.createProduct()
// 调用产品的方法
product.operation()
}
}
// 使用工厂方法模式创建产品 A 的客户端
factoryA = new ConcreteFactoryA()
clientA = new Client(factoryA)
clientA.run()
// 使用工厂方法模式创建产品 B 的客户端
factoryB = new ConcreteFactoryB()
clientB = new Client(factoryB)
clientB.run()
在这个示例中,工厂方法模式允许客户端使用一个通用的接口来创建产品,而具体的产品类型由具体的工厂子类来决定。这样一来,客户端代码与具体产品类之间的耦合性降低了,同时也便于扩展和维护。
举例:cocoa库NSNumber的设计
// 工厂方法模式示例:NSNumber
// 定义工厂接口
@protocol NumberFactory <NSObject>
- (NSNumber *)createNumberWithValue:(NSNumber *)value;
@end
// 具体工厂实现整数工厂
@interface IntegerFactory : NSObject <NumberFactory>
@end
@implementation IntegerFactory
- (NSNumber *)createNumberWithValue:(NSNumber *)value {
return [NSNumber numberWithInt:[value intValue]];
}
@end
// 具体工厂实现浮点数工厂
@interface FloatFactory : NSObject <NumberFactory>
@end
@implementation FloatFactory
- (NSNumber *)createNumberWithValue:(NSNumber *)value {
return [NSNumber numberWithFloat:[value floatValue]];
}
@end
// 客户端代码
NSNumber *value = @3.14;
id<NumberFactory> factory = [FloatFactory new];
NSNumber *number = [factory createNumberWithValue:value];
在上面的伪代码中,我们定义了一个 NumberFactory 接口,并创建了两个具体工厂类 IntegerFactory 和 FloatFactory。每个工厂类都实现了 createNumberWithValue: 方法来根据传入的值创建对应的 NSNumber 对象。客户端根据需要选择合适的工厂对象,并使用工厂对象来创建 NSNumber 对象。
高级用法-延迟初始化
高级用法-单例工厂模式
伪代码
工厂单例模式是一种设计模式,结合了工厂模式和单例模式的特点。它的目的是确保在整个应用程序中只有一个工厂实例,并且该工厂负责创建其他类的实例。
下面是工厂单例模式的伪代码示例:
plaintext
Copy code
// 工厂类,负责创建其他类的实例并确保只有一个工厂实例存在
class SingletonFactory {
private static SingletonFactory instance;
// 私有构造函数,防止外部创建新实例
private SingletonFactory() {}
// 静态方法获取工厂实例
public static SingletonFactory getInstance() {
if (instance == null) {
instance = new SingletonFactory();
}
return instance;
}
// 创建其他类的实例的方法
public SomeClass createInstance() {
return new SomeClass();
}
}
// 其他类的示例
class SomeClass {
// 一些属性和方法
}
// 客户端代码
class Client {
public static void main() {
// 获取工厂实例
SingletonFactory factory = SingletonFactory.getInstance();
// 使用工厂实例创建其他类的实例
SomeClass instance = factory.createInstance();
// 使用创建的实例
instance.doSomething();
}
}
在上面的示例中,SingletonFactory 是工厂单例模式的实现。它使用了单例模式确保只有一个工厂实例存在,并且提供了创建其他类实例的方法。客户端可以通过 getInstance() 方法获取工厂实例,并使用该实例创建其他类的实例。
其他
分析 抽象工厂模式和工厂方法模式 的区别
-
工厂方法模式:
工厂只能创建单一的产品
- 定义了一个接口或抽象类,该接口或抽象类负责创建产品对象。
- 具体的工厂类实现了该接口或抽象类,并负责创建具体的产品对象。
- 每个具体工厂类只能创建一种类型的产品。
-
抽象工厂模式:
工厂可以创建一组产品
- 定义了一个接口或抽象类,该接口或抽象类声明了一组创建相关或依赖对象的方法。
- 具体的工厂类实现了该接口或抽象类,并负责创建一组相关的产品对象。
- 每个具体工厂类可以创建一组相关的产品,而不仅限于单一类型的产品。
工厂和产品是否必须要遵守抽象的接口
非必需,但是把工厂、产品设计一个接口层,有利于后续拓展;建议设计一个抽象的接口;
工厂单例模式和单例模式的区别
不完全一样。虽然它们都涉及到创建单个实例,但它们的重点不同。
- 工厂单例模式(Factory Singleton Pattern) :这种模式结合了工厂模式和单例模式的特点。它包括一个工厂类,用于创建单例对象,并确保在应用程序中只存在一个实例。工厂单例模式将创建和管理单例对象的逻辑委托给一个工厂类,使得整个系统更加灵活和可扩展。
- 单例模式(Singleton Pattern) :单例模式是一种创建型设计模式,用于确保类只有一个实例,并提供一个全局访问点来访问该实例。它通常通过将类的构造函数设为私有,并提供一个静态方法来返回该类的唯一实例来实现。
虽然工厂单例模式可以使用单例模式来确保工厂类只有一个实例,但它们并不是同一概念。工厂单例模式的重点在于创建和管理对象实例,而单例模式的重点在于确保类只有一个实例。