生成器模式(Builder Pattern)

2019-11-20  本文已影响0人  iOS_学渣
生成器模式:用生成器模式封装一个产品的构造过程,并允许按步骤构造

生成器模式又称为建造者模式,是创建性模式中的一种。

生成器模式

生成器模式和工厂模式有些类似也有不同的地方。工厂模式用来封装生成一系列的产品(也是封装产品构造)。但是不同的地方是工厂模式步骤过程不变,即工厂模式是一套死的流程,而这里我们的生成器模式,可以根据自己需要而调整构造的步骤以及流程。

举个栗子

这次造车吧! 一辆车大概由轮子,轴承,底盘,引擎,外壳, 油漆,玻璃等等一些零部件组成。不同的车可能这些还不一样,有的车有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.产品的实现可以被替换,因为客户只看到了一个抽象的接口。

上一篇下一篇

猜你喜欢

热点阅读