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是否合法,域名是否匹配、是否是自签名证书、证书是否过时等。api

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>保持简洁性:保持代码和结构的简洁,每一个方法,每一个类,每一个包,每一个文件,都不要塞太多代码或资源,感受多了就应该拆分。
代码混乱的问题必须严格执行开发规范。mvc

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

MVC

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

  • 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

架构模式选择

  • 面向需求编程,以需求驱动编程
相关文章
相关标签/搜索