前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >架构之路 (二) —— APP架构分析(一)

架构之路 (二) —— APP架构分析(一)

原创
作者头像
conanma
修改2021-09-06 10:08:18
1.8K0
修改2021-09-06 10:08:18
举报
文章被收录于专栏:正则正则

回顾

上一篇主要讲述了苹果原生iOS框架的架构,这一篇我们就说一下如果自己要完成一个APP,需要如何去设计架构。


架构设计结构上划分

我们说APP的架构设计,但是架构设计需要我们怎么在结构上进行划分呢?可以按照下面进行划分。

  • 网络设计方案
    • 这里包括对网络层很好的设计和封装,让工程师可以方便安全的调用,同时也要保证用户在各种网络环境下有很好的体验。
  • 数据解析和页面渲染设计方案
    • 这里包括数据模型的搭建、页面如何封装降低耦合以及高效的渲染。
  • 数据持久化存储设计方案
    • 这里包括,当有本地存储的需求时,如何保证数据可以在本地合理的存储。
  • 动态部署方案
    • 这里包括,如何不发版就更新版本和解决问题。这个以前都用热更新hotfix,不需要发版就可以进行更新,但是苹果现在给禁掉了。现在还有一个可以解决部分问题的方案:可以采用云控,利用服务端进行控制,达到对某些功能的调控,但是还是不能通过热更新进行更新版本。

其实也可以有三层分层架构:展现层、业务层、数据层。

  • 展现层:视图页面渲染
  • 业务层:业务功能实现
  • 数据层:包括数据的下载(包含所谓的网络层)和转化,甚至持久化

好的架构衡量标准

  • 代码整齐,分类明确
    • 代码整齐是每一个工程师的基本素质,先不说你搞定这个问题的方案有多好,解决速度有多快,如果代码不整齐,一切都白搭。分类明确的字面意思大家一定都了解,但还有一个另外的意思,那就是:不要让一个类或者一个模块做两种不同的事情。如果有类或某模块做了两种不同的事情,一方面不适合未来拓展,另一方面也会造成分类困难。
  • 不用文档,或很少文档,就能让业务方上手
    • 尽可能让你的API名字可读性强,对于iOS来说,objc这门语言的特性把这个做到了极致,函数名长就长一点,不要紧。
  • 思路和方法要统一,尽量不要多元
    • 解决一个问题会有很多种方案,但是一旦确定了一种方案,就不要在另一个地方采用别的方案了。也就是做架构的时候,你得时刻记住当初你决定要处理这样类型的问题的方案是什么,以及你的初衷是什么,不要摇摆不定。另外,你当初设立这个模块一定是有想法有原因的,要记录下你的解决思路,不要到时候换个地方你又灵光一现啥的,引入了其他方案,从而导致异构。
  • 没有横向依赖,万不得已不出现跨层访问
    • 没有横向依赖是很重要的,这决定了你将来要对这个架构做修补所需要的成本有多大。要做到没有横向依赖,这是很考验架构师的模块分类能力和是否熟悉业务的。跨层访问是指数据流向了跟自己没有对接关系的模块。有的时候跨层访问是不可避免的,比如网络底层里面信号从2G变成了3G变成了4G,这是有可能需要跨层通知到View的。但这种情况不多,一旦出现就要想尽一切办法在本层搞定或者交给上层或者下层搞定,尽量不要出现跨层的情况。跨层访问同样也会增加耦合度,当某一层需要整体替换的时候,牵涉面就会很大。
  • 对业务方该限制的地方有限制,该灵活的地方要给业务方创造灵活实现的条件
    • 把这点做好,很依赖于架构师的经验。架构师必须要有能力区分哪些情况需要限制灵活性,哪些情况需要创造灵活性。比如对于Core Data技术栈来说,ManagedObject理论上是可以出现在任何地方的,那就意味着任何地方都可以修改ManagedObject,这就导致ManagedObjectContext在同步修改的时候把各种不同来源的修改同步进去。这时候就需要限制灵活性,只对外公开一个修改接口,不暴露任何ManagedObject在外面。如果是设计一个ABTest相关的API的时候,我们又希望增加它的灵活性。使得业务方不光可以通过Target-Action的模式实现ABtest,也要可以通过Block的方式实现ABTest,要尽可能满足灵活性,减少业务方的使用成本。
  • 易测试,易拓展
    • 要实现易测试易拓展,那就要提高模块化程度,尽可能减少依赖关系。如果是高度模块化的架构,拓展起来将会是一件非常容易的事情。
  • 保持一定量的超前性
    • 这一点能看出架构师是否关注行业动态,是否能准确把握技术走向。保持适度的技术上的超前性,能够使得你的架构更新变得相对轻松。另外,这里的超前性也不光是技术上的,还有产品上的。
  • 接口少,接口参数少
    • 越少的接口越少的参数,就能越降低业务方的使用成本。
  • 高性能
    • 高性能非常重要,但是在客户端架构中,它不是第一考虑因素。客户端业务变化非常之快,做架构时首要考虑因素应当是便于业务方快速满足产品需求,因此需要尽可能提供简单易用效果好的接口给业务方,而不是提供高性能的接口给业务方。

架构模式的选择

前面根据需求对框架的架构分类,可以分为三层结构甚至四层结构,这里就说一下架构模式,可以说架构模式是架构实现的方式。常见的有MVC、MVVM和VOPER等。好的架构模式可以让模块功能更清晰,维护起来也很方便。

下面就一起看一下这几种架构模式:

1. MVC
  • 任务均摊 – View和Model确实是分开的,但是View和Controller却是紧密耦合的
  • 可测试性 – 由于糟糕的分散性,只能对Model进行测试
  • 易用性 – 与其他几种模式相比最小的代码量。熟悉的人很多,因而即使对于经验不那么丰富的开发者来讲维护起来也较为容易。

MVC

这里MVC就不多说了,相信大家对它是最先接触也是最熟悉的了。

2. MVVM
  • 任务均摊 – 事实上,MVVM的View要比MVP中的View承担的责任多。因为前者通过ViewModel的设置绑定来更新状态,而后者只监听Presenter的事件但并不会对自己有什么更新。
  • 可测试性 – ViewModel不知道关于View的任何事情,这允许我们可以轻易的测试ViewModel。同时View也可以被测试,但是由于属于UIKit的范畴,对他们的测试通常会被忽略。
  • 易用性 – 在我们例子中的代码量和MVP的差不多,但是在实际开发中,我们必须把View中的事件指向Presenter并且手动的来更新View,如果使用绑定的话,MVVM代码量将会小的多。

MVVM

  • Controller主要作为调度者,居于中心位置。客串部分View相关功能。
  • ViewModel专门做“显示逻辑”,并且用属性观察者做绑定,必要的时候用Notification。
  • 在Swift中,ViewModel和Model推荐用Struct;Logic倾向于用class。从一个简单直观的概念来说,ViewModel需要保持轻量级,跟随页面走,随时准备修改。Model也是轻量级,跟随后台API定义走,只是个数据结构,随时准备修改。而Logic就显得比较大,考虑稳定,考虑复用。
  • 增加Logic类,负责业务逻辑,比如从网络取数据,修改数据库,检查用户名合法性,具体的响应逻辑,监听后的具体处理等等。
3. VIPER
  • 任务均摊 – 毫无疑问,VIPER是任务划分中的佼佼者。
  • 可测试性 – 不出意外地,更好的分布性就有更好的可测试性。
  • 易用性 – 最后你可能已经猜到了维护成本方面的问题。你必须为很小功能的类写出大量的接口。

VIPER

  • View: 也是View + Controller
  • Present:相当于ViewModel,叫展示器
  • Interactor:交互器,侧重于业务逻辑;从网络取数据,数据库等功能都在这里。
  • Entity:就是Model,仅仅是数据定义
  • WireFrame:就是Router,是页面跳转

参考文章

1. iOS应用架构谈 开篇 2. 我们常见的分层架构,有三层架构的:展现层、业务层、数据层。

后记

上面很多都是一些大牛的技术经验之谈,感兴趣的给个赞或者关注,谢谢~~~~

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 回顾
  • 架构设计结构上划分
  • 好的架构衡量标准
  • 架构模式的选择
  • 参考文章
  • 后记
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档