App架构-OC

1.制定安全机制

一个App,最核心的就是数据,而数据的主要来源就是API。

①保证API的调用者是经过自己授权的App

设计签名:对每个客户端,Android、iOS、WeChat,分 别分配一个AppKey和AppSecret。需要调⽤用API时,将AppKey加⼊请求参数列表,并将AppSecret 和所有参数一起,根据某种签名算法生成一个签名字符串,然后调用API时把该签名字符串也一起带上。服务端接收到这个请求时验证AppKey和AppSecret和签名字符串是否一致, 若一致则请求是安全的.每个端都有一个Key,也⽅便不同端的标识和统计。为了防止AppSecret被别人获取,这个AppSecret一般写死在代码⾥面。另外,签名算法也需要有一定的复杂度,不能轻易被别人破解,最好是采⽤自己规定的一套签名算法,⽽而不是采用外部公开的签名算法。另外,在参数列列表中再加⼊一个时间戳,还可以防止部分重放攻击 。

②保证数据传输的安全

采用HTTPS, HTTPS因为添加了SSL安全协议,自动对请求数据进行了压缩加密,在一定程度上可以防止监听、劫持、防止重发,主要就是防止中间人攻击。
为了安全考虑,建议对SSL证书进行校验,包括签名CA是否合法,域名是否匹配、是不是自签名证书、证书是否过期等。

2.接口协议标准化

每个技术团队一般都会有一份接口协议文档,包括对对每个接口的描述、入参、输出结果等。但一般并不严谨,很多地方没有同意标准,从而容易出现很多坑。有一份标准且严格执行的接口协议非常重要。协议的内容除了规定每个接口中每个数据具体的数据类型,还需要规定一套共用的数据字典,以及其他需要统一定义的信息,比如签名算法等。

3.接口版本控制

接口变动会导致旧版本App出错,而且变动不一定是修改了接口本身,有可能是增加了一种新的数据结构,客户端旧版本解析不了,从而就导致出错
为了解决接口的兼容性问题,需要做好接口版本控制。实现:
1.每个接口有各自的版本,一般为接口添加个version参数
2.整个接口系统有统一的版本,一般在URL中添加版本号,比如http://api.domain.com/v2
平时小版本更新,就采用第一种方式, 根据不同版本号做不同分支的处理;大版本采用第二种。(跟旧版本相对独立)
太旧的版本提醒用户强制升级或者普通升级。

4.架构分层(高内聚、低耦合)

数据管理、数据加工、数据展示,三层架构:数据层业务层展示层

  • 数据层是最底层,往下,接入API ;往上,向业务层交付数据;
  • 业务层处于中间层,数据的加工,将数据层提供上来的数据加工成展示层需要展示的数据。
  • 展示层处于最上层,主要将业务层取得的数据展示到界面上。

数据层:(数据管理者,封装API,并将数据交付给上层,中间会再加个数据缓存)

1>业务层向数据层请求数据;
2>数据层检查缓存中有没有请求需要的数据;
3>如果有缓存直接返回缓存数据;
4>如果没有缓存,则从网络API获取数据,并将数据加入缓存,然后返回数据。
调用API 时,还要判断网络状态,根据不同状态做不同处理。如果网络不可用,就无需发起请求。无网络可用时,也要区分是WIFI还是移动网络。连接移动网络时,一般要限制比较耗流量的请求。
获取分页数据时, 可以将下一页的数据预先请求、
缓存策略:对于获取数据的接口设置缓存。
数据层与外部交互:提供对外开放的数据接口。参数分为两类:系统参数和业务参数,像appKey、version、sign、time这些属于系统参数,而currentPage,或usderName的类则属于业务参数。
数据层开发的接口参数只需要包含业务参数就可以了,业务层并不需要关心系统参数是什么,系统参数在内部封装API时就已经指定了

业务层:(数据加工者)

从数据层获取数据,然后经过业务逻辑处理后转化成展示层需要的数据。(参数的有效性检查,注册成功后自动登录)
业务层交付给展示层的数据也是通过接口的方式,不同于数据层交付给业务层的是,给展示层的数据应该是通过异步回调返回的。因为获取数据是一个比较耗时的任务,通过异步回调才不会阻塞UI主线程。

展示层:(数据展示者)

关心数据如何展示:
界面布局、屏幕适配、图片资源、文本资源、颜色资源等等、
保持高质量代码
1>保持规范性:定义好开发规范,包括书写规范、命名规范、注释规范等,并按照规范严格执行;
2>保持单一性:布局就只做布局,内容就是只做内容,各自分离好,每个方法、每个类,也只做一件事情;(保持单一性是减低耦合度的关键标准,界面的单一就是要保持界面上每个维度做好分离,从界面布局到数据获取,数据检查,数据展示)。
3>保持简洁性:保持代码和结构的简洁,每个方法,每个类,每个包,每个文件,都不要塞太多代码或资源,感觉多了就应该拆分。
代码混乱的问题必须严格执行开发规范。

  • 环境分离:不同环境有不同的App。iOS可以通过创建多个环境的Target来实现环境分离,不同target可以设置不同的Bundle Identify , Bundle display name , 更换图标。每个Target也各自有自己的一份Plist文件,环境变量和第三方设置之类的,都可以设置在相应的plist文件里。
    模块之间不要存在相互调用的关系,以framework的形式存在。高内聚,高复用。

MVC

MVC 架构问题:
繁重的UI ,啰嗦业务逻辑,难受的用户代理,很长的网络层,内部方法,

  • VC代码过于繁重
  • 代码耦合性过高 (View和控制器耦合性强)

解决办法

  • 代码繁重(代码封装、抽取:谁的事情,谁干)
  • 耦合性高(解耦 eg:cell,setModel)
  • VC的任务是要建立依赖关系(依赖绑定)

MVP

面向协议,View和Model完全解耦,Controller层不显示网络请求数据的过程,只要遵循协议就能拿到数据
V层UI改变,通知P层,P层更新数据通知M层,M层拿到新数据通知P层,P层通知V层UI改变。
MVP 优缺点:
模型与视图完全分离,我们可以修改视图而不影响模型
②可以更高效的使用模型,因为所有的交互都发生在一个地方,Presenter内部
③我们可以将一个Presenter用于多个视图,而不需要改变Presenter的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
④如果我们把逻辑放在Presenter中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)

MVVM

KVO双向绑定
ViewModel作为枢纽,沟通View和Model之间的关系。

- (void)setWithViewModel:(MVVMViewModel *)vm {
    self.vm = vm;
    //KVO
    [self.vm addObserver:self forKeyPath:@"nameStr" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
    self.label.text = vm.nameStr;
}

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:    (NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"nameStr"]&&[change objectForKey:NSKeyValueChangeNewKey]) {
        NSNumber *new = [change objectForKey:NSKeyValueChangeNewKey];
        self.label.text = [NSString stringWithFormat:@"%@",new];
    }
}

-(void)mvvmClickChangModel{
    [self.vm clickChangeName];
}

//MVVMModel
#import "MVVMViewModel.h"

@implementation MVVMViewModel
-(void)setWithModel:(MVVMModel *)model{
    self.model = model;
    self.nameStr = model.name;
}
-(void)clickChangeName{
    self.model.name = [NSString stringWithFormat:@"name%d",arc4random()%10];
    self.nameStr = self.model.name;
    NSLog(@"%@",self.nameStr);
}
@end

架构模式选择

  • 面向需求编程,以需求驱动编程
posted @ 2019-02-25 11:17  淡然微笑_Steven  阅读(388)  评论(0编辑  收藏  举报