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的學習。