生成器模式:用生成器模式封装一个产品的构造过程,并允许按步骤构造
生成器模式又称为建造者模式,是创建性模式中的一种。
生成器模式生成器模式和工厂模式有些类似也有不同的地方。工厂模式用来封装生成一系列的产品(也是封装产品构造)。但是不同的地方是工厂模式步骤过程不变,即工厂模式是一套死的流程,而这里我们的生成器模式,可以根据自己需要而调整构造的步骤以及流程。
举个栗子
这次造车吧! 一辆车大概由轮子,轴承,底盘,引擎,外壳, 油漆,玻璃等等一些零部件组成。不同的车可能这些还不一样,有的车有4个轮子,有的车有8个轮子,有的车是柴油,有的车烧汽油...如果单纯的按照一套固定的流程构建车辆无法满足所有的情况。并且现在的车辆早就是流水线生产,而且不同的零部件可能来自于不同的地方。这样要适配各种情况会导致代码变得异常的复杂。
来吧,我们用生成器模式来组装车辆。来见识一下生成器模式的魅力。这里我们不做太复杂,只处理轮子,引擎,其他零部件太多,不打算全部展示出来。
生成器的接口(iOS中是协议)
#import <Foundation/Foundation.h>
@class Car;
NS_ASSUME_NONNULL_BEGIN
@protocol AbstractCarBuilder <NSObject>
-(void)createWheel:(NSString *)wheelName;
-(void)createEngine:(NSString *)engineName;
-(Car *)getCar;
@end
NS_ASSUME_NONNULL_END
生成器实现
#import "CarBuilder.h"
#import "Car.h"
#import "Engine.h"
#import "Wheel.h"
@interface CarBuilder ()
@property (nonatomic ,strong)Car * car;
@property (nonatomic ,strong)NSMutableArray * wheels;
@property (nonatomic ,strong)Engine * engine;
@end
@implementation CarBuilder
-(instancetype)init {
if (self = [super init]) {
_car = [[Car alloc] init];
_wheels = [NSMutableArray array];
}return self;
}
-(void)createWheel:(NSString *)wheelName {
Wheel * wheel = [[Wheel alloc] initWithName:wheelName];
[_wheels addObject:wheel];
}
-(void)createEngine:(NSString *)engineName {
Engine * engine = [[Engine alloc] initWithName:engineName];
_engine = engine;
}
-(Car *)getCar {
_car.wheels = [_wheels copy];
_car.engine = _engine;
return _car;
}
@end
汽车类 是具体的产品
#import <Foundation/Foundation.h>
#import "Wheel.h"
#import "Engine.h"
NS_ASSUME_NONNULL_BEGIN
@interface Car : NSObject
@property (nonatomic ,strong)NSArray <Wheel *>* wheels;
@property (nonatomic ,strong)Engine * engine;
@end
NS_ASSUME_NONNULL_END
#import "Car.h"
@implementation Car
-(NSString*)description
{
NSDictionary * info = @{ @"engine":_engine,
@"wheels":_wheels
};
return [NSString stringWithFormat:@"\n<%@:%p,\n\"%@\">",[self class],self.info];
}
@end
客户构建产品
这里我们可以看到生成器将构建汽车的过程分成了生成轮子和引擎,可以根据具体需求来的生成我们想要的产品
#import "CarClient.h"
#import "AbstractCarBuilder.h"
#import "Car.h"
@interface CarClient ()
@property (nonatomic ,strong)id <AbstractCarBuilder> builder;
@end
@implementation CarClient
-(instancetype)initWithBuilder:(id<AbstractCarBuilder>)builder {
if (self = [super init]) {
_builder = builder;
}return self;
}
-(Car *)constructCar {
for (int i = 0; i < 5; i++) {
NSString * wheelName ;
if (i == 4) wheelName = @"备胎";
else wheelName = [NSString stringWithFormat:@"轮胎%d",i];
[self.builder createWheel:wheelName];
}
[self.builder createEngine:@"涡扇15"];
return [self.builder getCar];
}
@end
我们可以看得到汽车的创建完全交给了CarBuider,我们客户可以根据具体的需求来定制产品的生产。
优点
1.将复杂的对象创建过程封装了起来。
2.允许对象通过多个步骤来创建,并且可以改变过程。
3.对客户隐藏了产品的实现
4.产品的实现可以被替换,因为客户只看到了一个抽象的接口。
网友评论