加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 站长资讯 > 评论 > 正文

一名一线开发对于App架构和组件化的思考

发布时间:2019-07-26 22:52:42 所属栏目:评论 来源:一线搬砖工人
导读:副标题#e# 写在前面 关于App架构、组件化,本文的内容不会涉及到具体代码层面,也不会介绍怎样使用Cocoapods去做组件化;而是站在软件工程的角度上,结合自己多年一线开发经验,去分析如何做App架构,如何通盘考虑什么样的架构才是合理的,契合自身业务的,
副标题[/!--empirenews.page--]

写在前面

关于App架构、组件化,本文的内容不会涉及到具体代码层面,也不会介绍怎样使用Cocoapods去做组件化;而是站在软件工程的角度上,结合自己多年一线开发经验,去分析如何做App架构,如何通盘考虑什么样的架构才是合理的,契合自身业务的,以及架构落地过程中应该规避哪些问题。

名词解释:本文中所提到的架构不是实际工程中代码架构(MVC、MVVM、MVP),确切的说是一种应用分层架构。而MVC、MVVM、MVP本质是一种软件架构模式,是App实现过程中的一种编码模式或者编码规范。

iOS系统架构回顾

一名一线开发对于App架构和组件化的思考

如上图所示,经典的iOS系统架构分为四层,自下而上分为核心操作系统层、核心服务层、媒体层、用户交互层。

Cocoa Touch:提供与用户交互的相关能力,包括触摸等,最常用的UIKit库就在该层;除此之外还有MapKit、Address BookUI、PhotosUI等。

Media Layer:提供图形与音视频相关功能的接口,例如Core Animation、OpenGL ES等。

Core Services:最常用的有Core Foundation、Foundation、CFNetwork、CoreData等。提供最基础的能力,比如数组、字典、HashMap、套接字等基础数据结构。

Core OS:包含Mach、Kernel、BSD、Socket以及Sandbox等,它主要提供了底层操作的接口,对于应用开发来讲直接用到的不是很多。

都说iOS系统牛逼,牛逼在哪?牛逼就牛逼在它有合理的架构分层,还有合理的Api设计,让你能够躺着就能做iOS开发,畅享丝滑!它牛逼的文件管理和文件隔离机制让你不需要过多考虑iOS系统安全性问题,逆向开发除外,因为它总是Bug般的存在????。

Q:iOS系统架构这四层之间是如何进行通信和交互的,是否合理?

A:直接引用头文件,调用下层提供的Api进行交互。关于是否合理,我想说的是只要Api设计的足够合理,足够能应对未来一段时间内SDK内部可能的变动,或者说SDK本身是一个很基础的库,比如Foundation库等,我觉得直接引入头文件无伤大雅,具体的我们稍后再讨论。

设计一个合理的应用分层架构

麻雀虽小五脏俱全,要想展翅高飞,每个环节缺一不可。

关于如何设计一个合理的应用分层架构,这里我们拿盖楼这件事做比喻,笔者干过建筑搬过砖,所以对于盖楼流程相对来说比较熟悉。

第一步:打地基、支模板、浇灌水泥搭架子、搬砖垒墙,这是一切的基础,高楼要屹立不倒,需要这些模块的长久有力的支撑才行。抽象到应用架构里面,我们称之为基础模块,其主要提供应用最基础的能力。

第二步:铺地面、造门,其中门在卧室、餐厅都可能会用到。抽象到应用架构里面,我们称之为公共业务模块,它主要提供了一些通用的业务模块或者通用的组件。

第三步:给大楼赋能,卧室、餐厅、洗漱间等一应俱全,有了这些才能真正体现盖大楼的意义。卧室等功能都要用到砖、墙、门等基础模块。在应用架构中,我们把卧室、厨房、洗漱等独立功能抽象为普通业务模块,每个业务模块都代表一个具体的功能,业务模块间没有强关联关系。

Q:除了以上的部分,是否还缺点什么东西?

A:楼层跟楼层之间需要电梯连接通信,卧室和厨房之间也需要通道进行连接。同样对于应用来讲,模块间的通信也需要一个媒介连接起来,我们称之为总线(Bus)。后续会详细介绍如何实现一个总线,让你的模块各自分工,且模块间的通信畅通无阻。

经过分析梳理,我们很容易能够画出如下的应用架构图,图中每层都标出了该层大致包含哪些内容。

一名一线开发对于App架构和组件化的思考

图中,我们按照“盖大楼”的思路,进一步抽象罗列出了一个App应该包含哪些结构。

应用架构实施落地

在iOS平台中,我们一般会通过Cocoapods去管理、集成自己的组件。按照工厂化生产App的理念,结合Cocoapods我画出了如下的App集成图。

一名一线开发对于App架构和组件化的思考

基础模块:因模块高度独立,且高频使用,若公司内部有多个App同时需要依赖,建议单独创建私有库Specs。

公共业务模块:功能相对独立,根据业务需求来决定是否单独创建私有库Specs。

Cocoapods公有库:所有公司内部App,强烈建议不要直接引入公有Specs。这样做有两点好处:

  1. 跟外部环境有效隔离,第三方库发生问题,公司内部可控。
  2. 公有库太大,每次repo update耗时太长,国内的环境你懂的,没有科学上网,至少一个小时过去repo也未必更新完毕。所以通用的方案是,若公司内部引用了第三方库,按照依赖倒置的原则,建议封装一层之后放到Basic Specs供业务方使用。在这里推荐一个科学上网工具,可自行搭建VPS->Vultr 。

又来到了一年一度的QA环节。

Q:如何把握组件拆分粒度?

A:没有一个可衡量的标准,需要结合具体业务场景,那些复用性高、功能相对独立就可以考虑做拆分。还有需要注意的是,组件拆分不一定要抽离成pod库,可以将有一定特性的一组通用组件打成一个pod库(姑且定义成CommonUIKit)。我们知道pod库最终都是生成静态库引用到主工程的,也就是最终都会经过链接的过程,pod库过多会带来一定的App启动性能开销,其次pod库过多也会导致pod管理混乱的问题。

Q:比如一个很小的功能,就一个弹框我需要去做解耦么,我抽成pod库别人直接引用不就得了?

A:在回答之前,我们先思考两个问题。弹框组件未来变动可能性有多大?你设计的Api是否合理,是否能够满足未来产品的需求?第二个问题,解耦带来的益处能够cover住这些可能的变动带来的弊端?想清楚这两个问题,我们就知道设计一个组件是否需要做解耦,是否需要用中间服务去除依赖了。

解决横向依赖

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读