Builder Pattern在IOS中的实际应用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ws_752958369/article/details/82792749

在说 Builder Pattern 之前,我们先来看看一个场景。假设我们要预定一个 iPhone 6,要 64G 的,金色的,用代码表述大概是这样:

// PFX 是一个前缀,因为直接写 iPhone6 不符合类名大写的习惯,写成 IPhone6 更是怪异 ╮(╯▽╰)╭
PFXiPhone6 *iphone = [[PFXiPhone6 alloc] init];
iphone.storage = 64;
iphone.color = [UIColor goldenColor];

也可以是另一种方式

PFXiPhone6 *iPhone = [[PFXiPhone6 alloc] initWithStorage:64 color:[UIColor goldenColor]];

实际上,以上两种方式分别代表了两种iOS对象的初始化方式。在未使用Builder Pattern之前,这两种初始化对象方式都有不方便的地方。第一种方法灵活,但是如果你接触iOS时间长点就会发现,经常会记不住这个类到底有哪些property需要初始化,尤其是当这个类是被人提供给你的时候!我们多么希望类的提供者能搞点注释啊啥的告知我们一下。第二种方法则很清晰地告诉调用者到底有哪些property需要在创建对象时初始化。但是,当类的提供者有天跟你说:hey,哥们,现在业务逻辑改变了,我增加了一个xxx属性,init方法也变了。这时,你是不是很想打他?每新增一个新的属性,init方法就要变动,而且当需要初始化的属性多大十几二十个时,这个init方法要不要太壮观!

所以,当某个类的属性值很多时,我们可以考虑使用建造者模式Builder Pattern来让初始化过程清晰一些,类的使用者会很感恩你这么做的。用iOS描述大概是这样的:

WSiPhone6 *iphone6 = [WSiPhone6 createWithBuilder:^(WSiPhone6Builder *builder) {
        builder.color = @"red";
        builder.storage = 64;
        builder.place = @"香港";
    }];
 NSLog(@"iphone6:%@",iphone6);
+(instancetype)createWithBuilder:(BuilderBlock)block
{
    NSParameterAssert(block != nil);
    WSiPhone6Builder *builder = [WSiPhone6Builder new];
    block(builder);
    return [builder build];
}
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class WSiPhone6;
@class WSiPhone6Builder;

typedef void(^BuilderBlock)(WSiPhone6Builder *);
NS_ASSUME_NONNULL_BEGIN

@interface WSiPhone6Builder : NSObject
@property (nonatomic,strong)UIColor *color;
@property (nonatomic,assign)NSInteger storage;
@property (nonatomic,copy)NSString *place;
@property (nonatomic,copy)NSString *size;
- (WSiPhone6 *)build;

@end

NS_ASSUME_NONNULL_END
#import "WSiPhone6Builder.h"
#import "WSiPhone6.h"

@implementation WSiPhone6Builder

-(WSiPhone6 *)build
{
    NSAssert(self.color, @"尺寸别忘记填写了");
    
    WSiPhone6 *iphone6 = [[WSiPhone6 alloc] init];
    iphone6.color = self.color;
    iphone6.storage = self.storage;
    iphone6.place = self.place;
    return iphone6;
    
    //return [[WSiPhone6 alloc] initWithBuilder:self];
}

@end

一些需要调用者强制初始化的参数可以build函数的开头处添加断言,一旦WSiPhone6Builder类的调用者在初始化时没有初始化color就是断言失败抛出异常。这在多人协同开发时可以省事很多。

然后发现IOS原生的UIAlertContoller也采用类似这种回调设置模式:

 UIAlertController *alerController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
    [alerController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
        
    }];

猜你喜欢

转载自blog.csdn.net/ws_752958369/article/details/82792749