iOS 架构杂谈

一. 开篇

1. 一句话概括客户端其实大部分都在干些什么事情?
    ---------------     ---------------     ---------------     ---------------
    |             |     |             |     |             |     |             |
    | 调用网络API  | --> |   展现列表    | --> |  选择列表    | --> |   展现单页   |
    |             |     |             |     |             |     |             |
    ---------------     ---------------     ---------------     ---------------
           ^                                                            |
           |                                                            |
           |                                                            |
            ------------------------------------------------------------
  • 简单来说就是调用 API,展示页面,然后跳转到别的地方再调用 API,再展示页面。
2. APP确实主要做这些事情,但是支持这些事情的基础,就是做架构要考虑的事情。(举三个)
  • 调用网络 API
  • 页面展示
  • 数据的本地持久化
3. 详细一点说明架构在上面三件事情的作用?
  • 如何让业务开发工程师方便安全地调用网络 API?然后尽可能保证用户在各种网络环境下都能有良好的体验?

  • 页面如何组织,才能尽可能降低业务方代码的耦合度?尽可能降低业务方开发页面的复杂度,提高他们的效率

  • 当数据有在本地存取的需求的时候,如何能够保证数据在本地的合理安排?如何尽可能地减少性能消耗

4. 架构设计的方法
  • 第一步:搞清楚要解决哪些问题,并找到解决这些问题的充要条件
  • 第二步:问题分类,分模块
  • 第三步:搞清楚各个问题直接的依赖关系,建立好模块交流规范并设计模块
  • 第四部:推演预测一下未来可能的走向,必要时添加新的模块,记录更多基础数据以备未来之需
  • 第五步:先解决依赖关系中最基础的问题,实现基础模块,然后再用基础模块堆叠出整个架构
  • 第六步:打点,跑单元测试,跑性能测试,根据数据去优化对应的地方
5. 什么样的架构叫好架构?
  1. 代码整齐,分类明确,没有 common,没有 core
  2. 不用文档,或很少文档,就能让业务方上手
  3. 思路和方法要统一,尽量不要多元
  4. 没有横向依赖,万不得已不出现跨层访问
  5. 对业务方该限制的地方有限制,该灵活的地方要给业务方创造灵活实现的条件
  6. 易测试,易拓展
  7. 保持一定量的超前性
  8. 接口少,接口参数少
  9. 高性能
6. 我们常说的三层架构或四层架构通常指的是什么?
  • 三层架构:展现层、业务层、数据层
  • 四层架构:展现层,业务层、网络层、本地数据层
7. 为什么流行起来的是三层架构,而不是四层架构或者五层架构
  • 因为所有的模块角色只会有三种:数据管理者、数据加工者、数据展示者
  • 笼统来说,软件只会有三层,每层扮演一个角色。
  • 其他的第四层第五层,一般都是这三层里面的其中之一分出来的,最后都能归纳进这三层的某一层中区,所以用三层架构来描述就比较普遍。
8. 三层架构MVC 之间是什么关系?
  • MVC 通常只是针对 三层架构中的 展现层 做的架构
  • 三层架构描述的侧重点是模块之间逻辑关系
  • MVC描述的侧重点在于数据流动方向

二. view 层的架构

1. 为什么说 view 层架构是最重要的?
  • View 层架构是最影响业务方迭代周期的因素之一
  • View 层架构是最贴近业务的底层架构
2. ViewController 代码结构的规定
  • 首先我们应该遵循苹果的代码设计规范 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/CodingGuidelines.html
  • 然后约定 ViewController 中的代码:先是 lifecycle,然后是 Delegate 方法实现,然后是 event response,接着是 private method ,最后才是 getters and setters
图片来源 https://casatwy.com/iosying-yong-jia-gou-tan-viewceng-de-zu-zhi-he-diao-yong-fang-an.html
  • viewDidLoad 里面只做 addSubview 的事情,然后 layoutPageSubviews 里面做布局的事情,最后在 viewDidAppear 里面做 Notification 的监听之类的事情。至于属性的初始化,则交给 getter 去做。
@interface CustomObject()
@property (nonatomic, strong) UILabel *label;
@end

@implement

#pragma mark - life cycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view addSubview:self.label];

    [self layoutPageSubviews];
}

- (void)layoutPageSubviews {
     [self.label addConstraints:xxxConstraints];
}

#pragma mark - getters and setters

- (UILabel *)label
{
    if (_label == nil) {
        _label = [[UILabel alloc] init];
        _label.text = @"1234";
        _label.font = [UIFont systemFontOfSize:12];
        ... ...
    }
    return _label;
}
@end
3. 在 10 以上的团队中,使用 nib代码写 View 哪种更优?

具有一定规模的团队化 iOS 开发(10 人以上)有以下几个特点:

  1. 同一份代码文件的作者会有很多,不同作者同时修改一份代码的情况也不少见。因此,用 Git 进行代码版本管理时出现 Conflict 的几率也比较大。
  2. 需要变换非常频繁,产品经理一时一个主意,为了完成需求二针对现有代码进行微调的情况,以及针对现有代码的 部分复用 的情况也比较多。
  3. 复杂界面元素、复杂动画场景的开发任务比较多。

综上所述:实现简单的东西,用Code一样简单,实现复杂的东西,Code比StoryBoard更简单。所以我更加提倡用code去画view而不是storyboard。

4. View 的布局采用什么方案?
  • 推荐采用 Masonry 方案,可读性强,可自动适配
  • CGRectMake 的话可读性很差,光看那几个数字,也无法知道 view 和 view 之间的位置关系。
  • 用原生 Autolayout 可读性稍微好点,但是生成的 constraint 的长度实在太差,代码观感不好
5. 是否有必要让业务方统一派生 ViewController?

// todo

6. 关于 MVC,请描述 Model,View,Controller 各做什么事情?

M 应该做的事情:

  1. 给 ViewController 提供数据
  2. 提供 ViewController 存储数据提供接口

C 应该做的事情:

  1. 管理 View Container 的生命周期
  2. 负责生成所有 View 的实例,并放入 View Container
  3. 监听来自 View 与业务有关的事情,通过与 Model 的合作,来完成对应事件的业务。

V 应该做的事情:

  1. 响应与业务无关的事件,如因此引发动画效果,点击反馈效果等。
  2. 界面元素表达

二. 网络层的架构

1. 如何确保 API 的调用者是来自你自己的 APP,防止竞争对手爬你的 API?
  • 服务端和客户端拿着同一个密钥。客户端发起请求时,将 API 名字和请求参数密钥摘要出一个 hash1 值,请求时带上这个 hash 值。 服务端拿到数据,用同一个密钥进行摘要出一个 hash2 值。如果 hash1hash2 相同就证明是来你自己的 APP。
  • 客户端保存这个密钥的时候,尽量不要存储到本地,直接写入代码中,被逆向的难度会大很多。
2. 如何防止中间人攻击,比如运营商很喜欢往用户的 HTTP 请求里面塞广告?
  • 使用 https
3. 网络层的优化方案(针对链接建立环节的优化)?
网络层的优化方案

三. 本地数据持久化层的架构

1. NSUserDefault
  • 一般来说,存放小规模数据,弱业务相关数据
  • 本质上就是类似 plist 的存储方式
2. keychain
  • Keychain 是苹果提供的带有可逆加密的存储机制,普遍用在各种存密码的需求上。
  • 另外,由于 APP 卸载只要系统不重装,Keychain 中的数据依旧能够得到保留,以及可被 iCloud 同步的特性,大家都会在这里存储用户的唯一标识。
3. 文件存储
  • 包括 Plist、archive、Stream 等方式
  • 一般结构化的数据或需要方便查询的数据,都会以 Plist 的方式去持久化
  • Archive 适合存储对象化的数据,Decode 比较花时间
  • Stream 就是一般文件存储,一般用于存存图片之类的,适合比较经常使用的
4. 数据库存储
  • 使用数据库最重要的目的就是 CRUD(增删改查)
  • 比较常见的是 FMDB

你可能感兴趣的:(iOS 架构杂谈)