生成器与建造房子
- 起房子的步骤可以对应三个抽象类:打地基类 / 建造类 / 装修类
- 建造过程的模块化处理,不同模块找不同的承包商
- 生成器的优点:你不需要知道细节 / 模块化处理 / 很好的组合特性
生成器模式实例
需要注意的是,这里有两个协议需要具体承包商来遵循
- 总协议.对所有模块承包商的要求 (BuilderProtocol)
- 类别协议。分别对各自类别的承包商要求 (AbstractPartOne , AbstractPartTwo)
AbstractPartOne
@protocol AbstractPartOne <NSObject>
@required
- (void)partOneBuilder;
@end
AbstractPartTwo
@protocol AbstractPartTwo <NSObject>
@required
- (void)buildTree;
- (void)buildSoureWithNumber;
@end
BuilderProtocol
@protocol BuilderProtocol <NSObject>
@required
- (id)build;
@end
Builder
@interface Builder : NSObject
@property (nonatomic, strong) id <BuilderProtocol, AbstractPartOne> partOne;
@property (nonatomic, strong) id <BuilderProtocol, AbstractPartTwo> partTwo;
- (id)builderAll;
@end
@implementation Builder
- (id)builderAll {
Builder *builder = [[[self class] alloc] init];
[builder.partOne build];
[builder.partOne build];
return builder;
}
@end
生成器与生产汽车
装配车间和组装产品(总指挥)
BuilderProtocol (这是对所有承包商的要求)
@protocol BuilderProtocol <NSObject>
@required
- (id)build;
@end
Builder
@interface Builder : NSObject
@property (nonatomic, strong) id <BuilderProtocol, AbstractEngine> engine;
@property (nonatomic, strong) id <BuilderProtocol, AbstractWheels> wheels;
@property (nonatomic, strong) id <BuilderProtocol, AbstractDoor> door;
@property (nonatomic, strong) NSDictionary *productsInfo;
- (void)buildAllParts;
@end
@implementation Builder
- (void)buildAllParts {
// 创建所有部件
[self.engine build];
[self.wheels build];
[self.door build];
NSMutableDictionary *dataDic = [NSMutableDictionary dictionary];
// 组装产品
dataDic[@"engine"] = [self.engine infomation];
dataDic[@"wheels"] = [self.wheels infomation];
dataDic[@"door"] = [self.door infomation];
self.productsInfo = dataDic;
}
@end
设计各个部件的生成器(模块承包)
AbstractDoor (对门模块承包商的要求)
@protocol AbstractDoor <NSObject>
@required
- (void)doorColor:(UIColor *)color;
- (NSString *)infomation;
@end
AbstractEngine (对引擎模块承包商的要求)
@protocol AbstractEngine <NSObject>
@required
- (void)engineScale:(CGFloat)scale;
- (void)engineWeight:(CGFloat)kg;
- (NSString *)infomation;
@end
AbstractWheels (对轮子模块承包商的要求)
@protocol AbstractWheels <NSObject>
@required
- (void)wheelsNumber:(NSNumber *)number;
- (NSString *)infomation;
@end
产品制造(具体施工队)
Door
@interface Door : NSObject <AbstractDoor, BuilderProtocol>
@end
- (void)doorColor:(UIColor *)color {
// todo
}
- (NSString *)infomation {
return @"X1-door, color : red";
}
- (id)build {
// todo
return nil;
}
@end
Engine
@interface Engine : NSObject <AbstractEngine, BuilderProtocol>
@end
@implementation Engine
- (void)engineScale:(CGFloat)scale {
// todo
}
- (void)engineWeight:(CGFloat)kg {
// todo
}
- (NSString *)infomation {
return @"X1-Engine, scale : 10, weight : 100";
}
- (id)build {
// todo
return nil;
}
@end
Wheels
@interface Wheels : NSObject <BuilderProtocol, AbstractWheels>
@end
@implementation Wheels
- (void)wheelsNumber:(NSNumber *)number {
// todo
}
- (NSString *)infomation {
return @"X1-wheels, number : 4";
}
- (id)build {
// todo
return nil;
}
@end
YEngine(替换Engine)
@interface YEngine : NSObject <AbstractEngine, BuilderProtocol>
@end
@implementation YEngine
- (void)engineScale:(CGFloat)scale {
// todo
}
- (void)engineWeight:(CGFloat)kg {
// todo
}
- (NSString *)infomation {
return @"Y-Engine, scale : 20, weight : 58";
}
- (id)build {
// todo
return nil;
}
@end
开始生产
ViewController
@interface ViewController ()
@property (nonatomic, strong) Builder *builder;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建组装者
self.builder = [[Builder alloc] init];
// 指定承包商
self.builder.engine = [[YEngine alloc] init];
self.builder.wheels = [[Wheels alloc] init];
self.builder.door = [[Door alloc] init];
// 构建所有的部件
[self.builder buildAllParts];
// 获取产品
NSLog(@"%@", self.builder.productsInfo);
}
@end
什么时候用protocol
1.对持有的属性有一定的要求,比如要求该属性必须实现某种方法。这时可以要求它遵循一个或多个协议,比如:
@property (nonatomic, strong) id <BuilderProtocol, AbstractPartOne> partOne;
2.对传入的值对象有一定的要求,比如比如要求它必须实现某种方法或返回某种类型。