创建者模式的使用,主要目的是提高代码的可维护性,如果需要对需求进行修改,不用重新修改方法和接口,根据参数或条件的不同处理。也就是对象的创建方法与初始化方式分离。
对CountryBuilder对象的初始化,使用带属性参数的方法进行初始化,如果需求要更改,需要再次添加一个location的属性,那就需要修改此方法,操作比较简单;如果某一天需要添加10几20个方法,再次修改方法就比较麻烦,而且方法也比较长。
0 // Countrybuilder.h 1 #import2 3 @interface CountryBuilder : NSObject 4 5 // 属性 6 @property(nonatomic,strong)NSString *capital; 7 @property(nonatomic,strong)NSString *name; 8 @property(nonatomic,assign)double area; 9 @property(nonatomic,assign)NSInteger population;10 11 // 带属性参数的初始化方法12 - (instancetype)initWithName:(NSString *)name13 capital:(NSString *)capital14 area:(double)area15 population:(NSInteger)population;16 @end
// Countrybuilder.m#import "CountryBuilder.h"@implementation CountryBuilder#pragma mark - 带属性参数列表的初始化方法- (instancetype)initWithName:(NSString *)name capital:(NSString *)capital area:(double)area population:(NSInteger)population{ self = [super init]; if(self){ self.name = name; self.capital = capital; self.area = area; self.population = population; } return self;}@end
此时,我们可以使用创建者模式,将对象的创建方法与属性设置分离开。这有点类似于我们先创建对象再使用set方法设置属性。但不同的是,创建者模式更加紧凑:
0 // CountryBuilder.h 1 #import2 3 @interface CountryBuilder : NSObject 4 5 typedef void(^CountryBlock)(CountryBuilder* country); 6 7 // 属性 8 @property(nonatomic,strong)NSString *capital; 9 @property(nonatomic,strong)NSString *name;10 @property(nonatomic,assign)double area;11 @property(nonatomic,assign)NSInteger population;12 @property(nonatomic,strong)NSString *location;13 14 // 使用创建者的初始化方法15 + (instancetype)createWithBuilder:(CountryBlock)builder;16 17 @end
0 // CouontryBuilder.m 1 #import "CountryBuilder.h" 2 3 @implementation CountryBuilder 4 5 #pragma mark - 使用创建者模式初始化方法 6 + (instancetype)createWithBuilder:(CountryBlock)builder{ 7 CountryBuilder *country = [[CountryBuilder alloc] init]; 8 if(builder == nil){} 9 else{10 builder(country);11 // 如果某些属性不能为空,则可以在此声明12 NSAssert(country.name, @"Country name is required.");13 }14 return country;15 }16 17 @end
在iOS 9中,创建消息弹框类UIAlertController中,对于对象的textField的设置也是使用了创建者方法进行构建:
1 UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Title" message:@"Message" preferredStyle:UIAlertControllerStyleAlert];2 [alert addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {3 textField.backgroundColor = [UIColor yellowColor];4 textField.placeholder = @"Please input name";5 }];