怎么做APIManager的继承?

如果要做成离散型的API调用,那么使用继承是逃不掉的。BaseAPIManager里面负责集约化的部分,外部派生的XXXAPIManager负责离散的部分,对于BaseAPIManager来说,离散的部分有一些是必要的,比如API名字等,而我们派生的目的,也是为了提供这些数据。

我在这篇文章里面列举了种种继承的坏处,呼吁大家尽量不要使用继承。但是现在到了不得不用继承的时候,所以我得提醒一下大家别把继承用坏了。

在APIManager的情况下,我们最直觉的思路是BaseAPIManager提供一些空方法来给子类做重载,比如apiMethodName这样的函数,然而我的建议是,不要这么做。我们可以用IOP的方式来限制派生类的重载。

大概就是长这样:

BaseAPIManager的init方法里这么写:
// 注意是weak。
@property (nonatomic, weak) id child;
- (instancetype)init { 
        self = [super init]; 
        if ([self conformsToProtocol:@protocol(APIManager)]) { 
                self.child = (id)self; 
        } else { 
              // 不遵守这个protocol的就让他crash,防止派生类乱来。
               NSAssert(NO, "子类必须要实现APIManager这个protocol。"); 
        } 
        return self;
}
    protocol这么写,把原本要重载的函数都定义在这个protocol里面,就不用在父类里面写空方法了:
    @protocol APIManager 
    @required
    - (NSString *)apiMethodName;
     ...
    @end
    然后在父类里面如果要使用的话,就这么写:
    [self  requestWithAPIName:[self.child apiMethodName] ......];

简单说就是在init的时候检查自己是否符合预先设计的子类的protocol,这就要求所有子类必须遵守这个protocol,所有针对父类的重载、覆盖也都以这个protocol为准,protocol以外的方法不允许重载、覆盖。

而在父类的代码里,可以不必遵守这个protocol,保持了未来维护的灵活性。

这么做的好处就是避免了父类写空方法,同时也给子类带上了紧箍咒:要想当我的孩子,就要遵守这些规矩,不能乱来。业务方在实现子类的时候,就可以根据protocol中的方法去一一实现,然后约定就比较好做了:不允许重载父类方法,只允许选择实现或不实现protocol中的方法。
关于这个的具体的论述在这篇文章里面有,感兴趣的话可以看看。

网络层与业务层对接部分的小总结

这一节主要是讲了以下这些点:

  • 使用delegate来做数据对接,仅在必要时采用Notification来做跨层访问
  • 交付NSDictionary给业务层,使用Const字符串作为Key来保持可读性
  • 提供reformer机制来处理网络层反馈的数据,这个机制很重要,好处极多
  • 网络层上部分使用离散型设计,下部分使用集约型设计
  • 设计合理的继承机制,让派生出来的APIManager受到限制,避免混乱
    应该不止这5点...

读完之后,感觉受益良多,打算把公司的项目网络层按照casa大神的网络设计方案给重构一下。

你可能感兴趣的:(怎么做APIManager的继承?)