美文网首页计算机技术一锅炖专题:临时区iOS学习笔记
利用多态及协议多重继承统一接口数据格式

利用多态及协议多重继承统一接口数据格式

作者: ifelseboyxx | 来源:发表于2017-04-17 23:24 被阅读252次

开始之前先简单说下需求:首先,页面样式由A部门负责,但是页面的数据依赖于B部门C部门B、C都有自己的唯一标识projectTag并且都有自己的接口,接口字段都不相同,他们的关系如下图:

在这种关系结构下就会导致一个问题:B接口C接口都有自己数据格式,A部门的页面到底用哪个接口?总不能用if else判断吧?万一还有部门D部门E呢?

利用协议实现多重继承

首先我们新建个协议 PublicProtocol.h,这个协议定义了页面VC所需要的数据元素(这里一般都定义成 readonly,不允许外部修改):

#ifndef PublicProtocol_h
#define PublicProtocol_h

@protocol DataInfoProtocol <NSObject>
@required
/** title */
@property (copy, nonatomic, readonly) NSString *title;
@optional
/** subTitle */
@property (copy, nonatomic, readonly) NSString *subTitle;
@end

#endif /* PublicProtocol_h */

然后我们在部门A部门B的接口Model中实现这个协议并返回所需要的数据:

//ClassAModel.h

#import <Foundation/Foundation.h>
#import "PublicProtocol.h"

@interface ClassAModel : NSObject
<DataInfoProtocol>

/** titleA */
@property (copy, nonatomic) NSString *titleA;

/** subTitleA */
@property (copy, nonatomic) NSString *subTitleA;

@end
//

#import "ClassAModel.h"

@implementation ClassAModel

#pragma mark - DataInfoProtocol setter

- (NSString *)title {
    return self.titleA;
}

- (NSString *)subTitle {
    return self.subTitleA;
}

@end

部门B的接口Model也类似:

//ClassBModel.h

#import <Foundation/Foundation.h>
#import "PublicProtocol.h"

@interface ClassBModel : NSObject
<DataInfoProtocol>

/** titleB */
@property (copy, nonatomic) NSString *titleB;

/** subTitleB */
@property (copy, nonatomic) NSString *subTitleB;

@end
//ClassBModel.m

#import "ClassBModel.h"

@implementation ClassBModel
#pragma mark - DataInfoProtocol setter

- (NSString *)title {
    return self.titleB;
}

- (NSString *)subTitle {
    return self.subTitleB;
}

@end

这样我们就解决了不同接口参数不一样的问题,统一了接口字段。接着我们还有个问题:

该怎么传递数据给页面VC

利用多态特性传递数据

首先我们新建个抽象数据源基类 BaseClass.h,里面定义好 页面VC所需要的数据源:

//BaseClass.h

#import "PublicProtocol.h"

@interface BaseClass : NSObject

/** 数据源*/
@property (strong, nonatomic) NSArray <id<DataInfoProtocol>> *dataList;

/** 接口请求操作*/
- (void)fetchDataWithCompletionHandler:(void(^)())completeBlock;
@end

这里返回的数据源是一个实现 DataInfoProtocol 协议的对象数组 dataList

接着每个部门都包含一个BaseClass的子类,比如 部门A 的数据源类 ClassA.h

//ClassA.h

#import "BaseClass.h"

@interface ClassA : BaseClass

@end

//ClassA.m

#import "ClassA.h"
#import "ClassAModel.h"

@implementation ClassA

- (void)fetchDataWithCompletionHandler:(void (^)())completeBlock {
    
    //模拟请求接口操作
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSDictionary *tempDict = @{@"titleA"    : @"Jhons",
                                   @"subTitleA" : @"iOS dev"};
        ClassAModel *aModel = [ClassAModel classAModelWithDict:tempDict];
        self.dataList = @[aModel];
        
        completeBlock();
    });
    
}

- (void)dealloc {
    NSLog(@"%@dealloc",self.class);
}

@end

这里模拟了请求接口,返回了 A接口 的数据源,B部门 也类似。

接着,我们申明抽象数据源类 BaseClass

/** Data Class */
@property (strong, nonatomic) BaseClass *dataClass;

然后我们就可以根据每个部门的projectTag标识,来创建不同的数据源类:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"ProjectMaps" ofType:@"plist"];
    NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
    self.dataClass = [NSClassFromString(dictionary[self.projectTag]) new];
    
    [MBProgressHUD showHUDAddedTo:self.view animated:YES];
    [self.dataClass fetchDataWithCompletionHandler:^{
        [MBProgressHUD hideHUDForView:self.view animated:YES];
        [self.tvDetial reloadData];
    }];
}

这里我用了个 ProjectMaps.plist,来根据每个项目的projectTag 标识,定义好数据源类:

写的例子比较简单,但是设计思路应该很明白了,具体效果如下:

写在最后

可能这并不是最后的设计模式,如果有更好地,希望能一起讨论下 ^ ^

最后 附上 Demo

相关文章

  • 利用多态及协议多重继承统一接口数据格式

    开始之前先简单说下需求:首先,页面样式由A部门负责,但是页面的数据依赖于B部门和C部门,B、C都有自己的唯一标识p...

  • 编程第三周的日常<二>

    接口与多态 接口 一种特殊的类,是一种抽象类的延伸。 接口之间允许继承而且允许多重继承---一个接口可以继承多个接...

  • 2017 09 20

    结合9.20日所学的继承,多重继承及指针等相关知识,对多态及虚函数进行学习,主要练习为图形类的多态、虚函数的实际应...

  • Java基础7-异常;jar包

    昨日内容回顾 多态:多种状态,多态的前提条件是继承或者是实现 面向接口编程降低耦合度接口是最低标准,接口可以多重继...

  • jvm结构&运行机制&多态实现

    浅析Java虚拟机结构与机制 浅谈多态机制的意义及实现 多态:编译时多态(重载)、运行时多态(继承父类、实现接口)...

  • 程序组第二次作业代码

    继承与多态: 接口作业:

  • Java面向对象编程——封装和继承

    面向对象是编程的重点,涉及到类的封装、继承、抽象、多态及接口的设计等。其中,封装、继承、多态是面向对象的三大特征。...

  • iOS封装、继承、多态

    0、iOS中面向对象3个特征:封装、继承、多态 1、iOS不支持多重继承,需要用遵循多个协议来实现 2、面向对象的...

  • Java中关于多重继承的问题

    多重继承的含义 一.用接口实现多重继承 二.用内部类实现多重继承

  • 《Java8学习笔记》读书笔记(八)

    第7章 接口与多态 学习目标 使用接口定义 了解接口的多态操作 利用接口枚举常数 利用enum枚举常数 7.1 ...

网友评论

  • BierLee:个人认为协议多重继承是对其他项目的数据的污染,本来不相关的ClassModelA,B只是一个数据model,不该有其他的业务逻辑,却要实现同一个protocol,不如直接transform
    ifelseboyxx:transform 意思是 提供个方法来转换数据?
  • BierLee:大湿,Demo的地址有问题吧
    ifelseboyxx:已修复

本文标题:利用多态及协议多重继承统一接口数据格式

本文链接:https://www.haomeiwen.com/subject/mrvxzttx.html