填充数据的模型和机制常见的两种方案

1、使用自定义初始化器
-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender;
-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender{
    if (self = [super init]) {
        //进行赋值操作
        self.userId = userId;
        .....
    }
    return self;
}

使用自定义初始化器会有很长的方法名,并且加入更多属性时不会向下兼容。
但也领使用新版模型的应用能在编译时知道了什么地方发生了改变。

2、使用生成器模式
//构建一个生成器
#import 
NS_ASSUME_NONNULL_BEGIN
//@class防止互相引用,死循环
@class User;

@interface UserBuilder : NSObject

@property (nonatomic , copy) NSString *userId;
@property (nonatomic , copy) NSString *firstName;
@property (nonatomic , copy) NSString *lastName;
@property (nonatomic , copy) NSString *gender;

- (User *)build;
//构建对象,一个例子
//用生成器构建的对象
-(User *)createUser;
@end

NS_ASSUME_NONNULL_END

#import "UserBuilder.h"
#import "User.h"
@implementation UserBuilder
//build方法实现
-(User *)build{
    return [[User alloc]initWithUserBuilder:self];
}
//构建对象,一个例子
-(User *)createUser{
    User *user = [User userWithBlock:^( UserBuilder *builder ) {
        builder.userId = @"001";
        builder.firstName = @"First";
        builder.lastName = @"Last";
        builder.gender = @"F";
    }];
    return user;
}

@end
#import 
@class UserBuilder;
NS_ASSUME_NONNULL_BEGIN

@interface User : NSObject
@property (nonatomic , copy) NSString *userId;
@property (nonatomic , copy) NSString *firstName;
@property (nonatomic , copy) NSString *lastName;
@property (nonatomic , copy) NSString *gender;
//模型提供的类方法
+(instancetype)userWithBlock:(void(^)(UserBuilder *))block;
//模型的私有扩展--自定义初始化器
-(instancetype)initWithUserBuilder:(UserBuilder *)builder;

//-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender;
@end

NS_ASSUME_NONNULL_END
#import "User.h"
#import "UserBuilder.h"

@implementation User
//模型自定义初始化
-(instancetype)initWithUserBuilder:(UserBuilder *)builder{
    if (self = [super init]) {
        self.userId = builder.userId;
        self.firstName = builder.firstName;
        self.lastName = builder.lastName;
        self.gender = builder.gender;
    }
    return self;
}
//方法实现
+(instancetype)userWithBlock:(void (^)(UserBuilder * _Nonnull))block{
    UserBuilder *builder = [[UserBuilder alloc]init];
    block(builder);
    return [builder build];
}

//-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender{
//    if (self = [super init]) {
//        //进行赋值操作
//        self.userId = userId;
//        .....
//    }
//    return self;
//}

@end
//内部核心构建模型
UserBuilder *builder = [[UserBuilder alloc]init];
User *u = [builder createUser];

//调用者使用build方法构建模型
builder.userId = @"000";
builder.firstName = @"name";
builder.lastName = @"last";
builder.gender = @"AAA";
User *builderUser =[builder build];

    

优点
模型总是向下兼容的,新版模型生成器包含了新的属性,不会破话createUser的代码,
生成器可以直接创建,调用者也可以初始化生成器,并且调用build方法创建模型对象
生成器的创建和处理可以留给内部核心完成。模型调用者可以使用userWithBlock:,无需初始化或亲自调用build方法

Tips:头文件互相引用问题(头文件导入循环引用)

引入头文件的时机尽量延后,只有在有需要的地方才引用,这样就可以减少类所需引入头文件的数量,使用向前声明,如果要编译A类,编译器就要知道B类文件,但是要编译B,则需要知道A,这样就会导致循环引用。
此时就需要使用@class+类文件,这样只是声明了这个名称是类的名称。至于是如何定义的编译器不需要完全知道。
然后在.m中import,import就会包含这个类的所有信息,包括实体变量和方法。

你可能感兴趣的:(填充数据的模型和机制常见的两种方案)