如何为使用数据创建的单例维护适当的封装

How to maintain proper encapsulation for singleton created with data

我有一个单例网络 class 以及一个需要在我的应用程序中持续存在的单例对象。单例是根据从网络调用中检索到的数据进行初始化的,所以现在我的代码可以正常工作,并且我的单例网络中有以下内容 class:

- (void)initializeObjectWithSuccess:(void (^)(BOOL))success
                                 failure:(void (^)(NSError *error))failure {
[self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
    id json = [NSJSONSerialization JSONObjectWithData:responseObject
                                              options:NSJSONReadingAllowFragments
                                                error:nil];

    [[CPList sharedList] setIdentifier:json[@"id"]];
    [[CPList sharedList] setImages:json[@"images"]];
    if (success) {
        success(YES);
    }

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    failure(error);
}];
}

我不知道如何在我的单例 CPList 上初始化我需要的所有属性而不在此方法中设置它们,但是我知道这不是正确的封装,因为 CPRequestManager Class 应该一无所知CPList Class

如果您的问题是您不希望此 class 知道 CPList 的名称以及它是单例的详细信息,并且它可以通过 +[CPList sharedInstance] 访问它那么你可以传入一个符合协议的对象。这基本上将单身人士的知识转移到其他地方

- (void)initializeObjectWithList:(id<CPList>)list
                         success:(void (^)(BOOL))success
                         failure:(void (^)(NSError *error))failure;
{
  [self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
      id json = [NSJSONSerialization JSONObjectWithData:responseObject
                                                options:NSJSONReadingAllowFragments
                                                  error:nil];


      [list setIdentifier:json[@"id"]];
      [list setImages:json[@"images"]];
      if (success) {
          success(YES);
      }

  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      failure(error);
  }];
}

或者您可以删除所有存在 "list" 的知识,只使用此方法 return 实际数据,然后调用者可以将其设置在列表中

- (void)initializeObjectWithSuccess:(void (^)(NSString *ID, NSArray *images))success
                            failure:(void (^)(NSError *error))failure;
{
  [self.HTTPClient postPath:[NSString stringWithFormat:@"users/%@/", [CPUser sharedUser].name parameters:[self createParameters] success:^(AFHTTPRequestOperation *operation, id responseObject) {
      id json = [NSJSONSerialization JSONObjectWithData:responseObject
                                                options:NSJSONReadingAllowFragments
                                                  error:nil];

      if (success) {
          success(json[@"id"], json[@"images"]);
      }

  } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      failure(error);
  }];
}

没有任何进一步的上下文,很难提出结构更改的建议,但这里有两个潜在的重构可能会让您思考您可以做什么