如何在ObjC中用Builder模式创建一个不可变的对象



我正在努力在ObjC中创建一个具有构建器模式的不可变对象。假设我有一个用户对象,它具有以下属性:

  1. 名字
为了确保不变性,我建议使用以下代码:
@protocol User
@property (nonatomic, strong, readonly) NSString *const firstName;
@property (nonatomic, strong, readonly) NSString *const lastName;
@end
@interface User: NSObject<User>
- (instancetype)initWithFirstName:(NSString *)fName withLastName:(NSString *)lName;
@end
@implementation User
@synthesize firstName;
@synthesize lastName;
- (instancetype)initWithFirstName:(NSString *)fName withLastName:(NSString *)lName
{
    NSParameterAssert(fName);
    NSParameterAssert(lName);
    if (self = [super init]) {
        self->firstName = [fName copy];
        self->lastName = [lName copy];
    }
    return self;
}
@end

我真正挣扎的是如何实现这个不可变对象的构建器?

关于Builder的有用链接:

ObjC中的Builder模式

Builder模式定义

您上面发布的链接使用两个对象来实现构建器模式。一个专用的构建器对象,随后传递给返回要构建对象的create/build方法。下面是一个用不可变对象实现构建器模式的完全人为的例子。

首先创建一个不可变对象;将由builder对象构建的对象。

@interface Person: NSObject
@property (nonatomic, readonly) NSString *firstName;
@property (nonatomic, readonly) NSString *lastName;
@end
@implementation Person
- (instancetype)initWithFirstName:(NSString *)firstName lastName:(NSString *)lastName{
     self = [super init]
     if(!self) return nil;
     _firstName = [firstName copy];
     _lastName = [lastName copy];
     return self;
}
@end

现在让我们创建构建器对象。

@interface PersonBuilder: NSObject
@property (nonatomic, strong) NSString *firstName; 
@property (nonatomic, strong) NSString *lastName;
- (Person *)create;
@end
@implementation PersonBuilder
- (Person *)create{
     return [[Person alloc] initWithFirstName:self.firstName lastName:self.lastName];
}
@end

实现类

PersonBuilder *builder = [PersonBuilder new];
builder.firstName = "John";
builder.lastName = "Doe";
Person *john = [builder create];

在Objective-C中,我真的没有看到任何好的理由来实现构建器模式,除非你试图避免一个冗长而令人困惑的构造函数签名,或者如果一个对象只是有两个许多属性或选项,如NSDateComponent。构建器模式本质上允许您将复杂的不可变对象的初始化拆分为多个简单的setter调用。在构建器上实现的create/build方法还为您提供了一个钩子点,您可以在其中验证对象是否正在按您的需要创建。我只在极少数情况下使用这种模式。

最新更新