定义
当我们想让用户获取产品不需要关心对象的创建过程和细节,我们可以考虑使用建造者模式。例如当开发商在建造大楼时,他们不需要去参与整栋楼是如何建造的过程,建楼的事情一般给到建筑公司去完成,在建造过程中,建楼的图纸就可以看成我们的抽象建筑者角色;而工人可通过图纸来知道这栋楼是要怎么建的,当然工人就是我们的具体建造者角色;但是呢,工人知道了这栋楼怎么建,但是他该从哪里建起呢,这时我们的工程师就充当了指挥者这个角色,指挥工人的建楼的整个过程。最后通过我们的工程师和工人的努力,完成了开发商所交付的大楼(具体产品)。
角色
建造者模式包含以下角色:
- 具体产品角色:封装生成的复杂对象类型(大楼)
- 抽象建造者角色:定义了公共复杂对象的创建及属性赋值的相关接口(图纸)
- 具体建造者角色:继承自抽象建造者类,实现不同属性的具体产品(工人)
- 指挥者角色:使对象的创建与表示相分离,并指挥了复杂对象各属性赋值实现了逻辑处理(工程师)
代码
/** 具体产品角色 CarProduct类 **/
// CarProduct.h
@interface CarProduct : NSObject
@property (nonatomic, copy) NSString *carTop;
@property (nonatomic, copy) NSString *carHead;
@property (nonatomic, copy) NSString *carBody;
@property (nonatomic, copy) NSString *carTail;
@end
// CarProduct.m
#import "CarProduct.h"
@implementation CarProduct
@end
/** 抽象建造者角色 BaseBuilder类 **/
// BaseBuilder.h
@interface BaseBuilder : NSObject
- (void)createCarHead;
- (void)createCarTop;
- (void)createCarTail;
- (void)createCarBody;
@end
// BaseBuilder.m
#import "BaseBuilder.h"
@implementation BaseBuilder
@end
/** 具体建造者角色 JZSportCarBuilder类 **/
// WorkerBuilder.h
#import "BaseBuilder.h"
@class CarProduct;
@interface WorkerBuilder : BaseBuilder
- (CarProduct *)CarProduct;
@end
// WorkerBuilder.m
#import "WorkerBuilder.h"
#import "CarProduct.h"
@interface WorkerBuilder()
{
WorkerBuilder *_workerBuilder;
CarProduct *_carProduct;
}
@end
@implementation WorkerBuilder
- (CarProduct *)CarProduct {
_workerBuilder = self;
_carProduct = [CarProduct new];
[_workerBuilder createCarTop];
[_workerBuilder createCarBody];
[_workerBuilder createCarHead];
[_workerBuilder createCarTail];
return _carProduct;
}
- (void)createCarTop {
NSLog(@"车顶组装成功");
}
- (void)createCarBody {
NSLog(@"车身组装成功");
}
- (void)createCarHead {
NSLog(@"车头组装成功");
}
- (void)createCarTail {
NSLog(@"车尾组装成功");
}
@end
/** 指挥者角色 Director类 **/
// Director.h
@class CarProduct;
@interface Director : NSObject
- (CarProduct *)getCarProduct;
@end
// Director.m
#import "Director.h"
#import "WorkerBuilder.h"
#import "CarProduct.h"
@implementation Director
- (CarProduct *)getCarProduct {
WorkerBuilder *workerBuilder = [WorkerBuilder new];
CarProduct *carProduct = [workerBuilder CarProduct];
return carProduct;
}
@end
/** 生成复杂对象具体实现 **/
Director *carDirector = [Director new];
CarProduct *carProduct = [carDirector getCarProduct];
NSLog(@"%@, %@, %@, %@", carProduct.carTop, carProduct.carHead, carProduct.carBody, carProduct.carTail);
这里我通过具体建造者类,可以更加直观地突出建造者模式的各个角色用处!
优点
- 在建造者模式中,将复杂对象的创建与表示进行解耦,相同的创建过程可以生成不同的产品对象;
- 每一个建造者相互独立,可以通过不同的建造者生成不同的产品对象;
- 对具体产品进行封装,可以更加精细地控制产品的创建过程;
- 增加新的具体建造者无须修改原有类库的代码,符合开闭原则;
缺点
- 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制;
- 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大;
使用场景
- 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性,相同的创建方法可生成不同的产品对象。
- 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
- 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。