缘由
在工厂模式中,具体工厂只负责出具体的产品,每一个具体工厂对应一个具体产品;工厂方法也具有唯一性,一个具体工厂方法中只有一个或一组重载的工厂方法。当我们所生产的具体产品不是一个简单的对象,而是拥有多个不同产品等级结构的具体产品对象组成,此时需要我们使用抽象工厂模式!
定义
抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。
模式结构
- AbstractFactory:抽象工厂,包含生成对应不同产品等级结构的方法;
- ConcreteFactory:具体工厂,实现生成所需不同的产品等级结构的具体产品对象;
- AbstractProduct:抽象产品,定义了一些产品需要统一实现的方法;
- Product:具体产品,生成不同实例对象;
案例
/** 产品类 **/
// BaseButton 抽象按钮Ben产品类
@interface BaseButton : UIButton
- (void)userBtn;
@end
@implementation BaseButton
@end
// BaseLabel 抽象文本Label产品类
@interface BaseLabel : UILabel
- (void)userLabel;
@end
@implementation BaseLabel
@end
// CircleButton 具体按钮Btn产品类
@interface CircleButton : BaseButton
@end
@implementation CircleButton
- (void)userBtn {
NSLog(@"当前正在使用按钮:%@", NSStringFromClass([self class]));
}
@end
// SquareLabel 具体文本Label产品类
@interface SquareLabel : BaseLabel
@end
@implementation SquareLabel
- (void)userLabel {
NSLog(@"当前正在使用文本:%@", NSStringFromClass([self class]));
}
@end
/** 工厂类 **/
// AbstractFactory 抽象工厂类
@interface AbstractFactory : NSObject
+ (BaseButton *)createButton;
+ (BaseLabel *)createLabel;
@end
@implementation AbstractFactory
@end
// AbstractFactory 具体工厂类
@interface UIFactory : AbstractFactory
@end
@implementation UIFactory
+ (BaseButton *)createButton {
BaseButton* circleBtn = [[CircleButton alloc] init];
return circleBtn;
}
+ (BaseLabel *)createLabel {
BaseLabel* squareLabel = [[SquareLabel alloc] init];
return squareLabel;
}
@end
// 在需要实现的地方进行调用
- (void)viewDidLoad {
[super viewDidLoad];
BaseButton* btn = [UIFactory createButton]; // 生成具体的按钮
BaseLabel* label = [UIFactory createLabel]; // 生成具体的文本
[btn userBtn];
[label userLabel];
}
- 定义抽象产品类,通过继承实现延伸出各种不同具体产品;
- 定义抽象工厂类,通过继承实现创建不同的产品方法来生成对象;
优点
- 抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建;
- 增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点
- 在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
- 开闭原则的倾斜性,因为增加新的工厂和产品族容易,但是增加新的产品等级结构需要去改变抽象工厂类,所以违反开闭原则。