7.Builder Pattern的學習和使用

1.面臨的問題:

       我們通常在初始化一個對象時,需要給該對象的一些屬性進行賦值,比如下面這個類:

typedef enum
{
    sexTypeMale,
    sexTypeFamle
} sexType;

@interface CYLPerson : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) sexType sex;

       當我們要給person對象的屬性賦值時,一種方法是提供一個init方法,在這個init方法中約束需要被賦值的屬性:  

-(instancetype)initWithName:(NSString *)name age:(int)age andSex:(sexType)sex
{
    self = [super init];
    if (self)
    {
        _name = name;
        _age = age;
        _sex = sex;
    }
    return self;
}
      這樣的好處是可以約束使用者必須賦值所有需要賦值的屬性,壞處是代碼沒有很好的可擴展性,當該類有一個新的屬性增加時,又必須新聲明一個方法,這樣太麻煩。

      另一種方法是,直接alloc,init之後,然後對屬性成員一一賦值,這樣雖然可擴展,但是無法約束使用者對必須賦值的屬性進行賦值。

      基於以上兩種方法的缺點,我們就可以使用 Builder Pattern 來解決上面的問題:

2.Build Pattern

      先來看看利用Builder Pattern 是如何進行初始化的:

CYLPerson *person = [CYLPerson creatWithBuilder:^(CYLPersonBuilder *builder) {
        builder.name = @"張三";
        builder.age = 78;
        builder.sex = sexTypeFamle;
    }];
    NSLog(@"%@",person.name);
     這裏我們引入了另外一個類:CYLPersonBuilder,利用該類來進行屬性賦值,並在該類中檢查需要被賦值的屬性是否全部被初始化了。下面是這個類方法的代碼:

typedef void (^BuilderBlock)(CYLPersonBuilder *);

+(instancetype)creatWithBuilder:(BuilderBlock)block;

+(instancetype)creatWithBuilder:(BuilderBlock)block
{
    CYLPersonBuilder *builder = [[CYLPersonBuilder alloc]init];
    block(builder);
    return [builder build];
}

     build方法的代碼如下:

-(CYLPerson *)build
{
    NSAssert(_name, @"name屬性未進行初始化");
    NSAssert(_age, @"age屬性未進行初始化");
    NSAssert(_sex, @"sex屬性未進行初始化");
    
    CYLPerson *person = [[CYLPerson alloc]init];
    person.name = _name;
    person.age = _age;
    person.sex = _sex;

    return person;
}

       這樣我們在build方法中檢查了需要約束的屬性,並且增強了代碼的可擴展性。

       以上便是關於Builder Pattern的學習。







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章