内容简介:写在前面关于App架构、组件化,本文的内容不会涉及到具体代码层面,也不会介绍怎样使用Cocoapods去做组件化;而是站在软件工程的角度上,结合自己多年一线开发经验,去分析如何做App架构,如何通盘考虑什么样的架构才是合理的,契合自身业务的,以及架构落地过程中应该规避哪些问题。名词解释:本文中所提到的架构不是实际工程中代码架构(MVC、MVVM、MVP),确切的说是一种应用分层架构。而MVC、MVVM、MVP本质是一种软件架构模式,是App实现过程中的一种编码模式或者编码规范。
写在前面
关于App架构、组件化,本文的内容不会涉及到具体代码层面,也不会介绍怎样使用Cocoapods去做组件化;而是站在软件工程的角度上,结合自己多年一线开发经验,去分析如何做App架构,如何通盘考虑什么样的架构才是合理的,契合自身业务的,以及架构落地过程中应该规避哪些问题。
名词解释:本文中所提到的架构不是实际工程中代码架构(MVC、MVVM、MVP),确切的说是一种应用分层架构。而MVC、MVVM、MVP本质是一种软件架构模式,是App实现过程中的一种编码模式或者编码规范。
iOS系统架构回顾
如上图所示,经典的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应该包含哪些结构。
应用架构实施落地
在iOS平台中,我们一般会通过Cocoapods去管理、集成自己的组件。按照工厂化生产App的理念,结合Cocoapods我画出了如下的App集成图。
-
基础模块:因模块高度独立,且高频使用,若公司内部有多个App同时需要依赖,建议单独创建私有库Specs。
-
公共业务模块:功能相对独立,根据业务需求来决定是否单独创建私有库Specs。
-
Cocoapods 公有库 :所有公司内部App,强烈建议不要直接引入公有Specs。这样做有两点好处:
1.跟外部环境有效隔离,第三方库发生问题,公司内部可控。
2.公有库太大,每次repo update耗时太长,国内的环境你懂的,没有科学上网,至少一个小时过去repo也未必更新完毕。所以通用的方案是,若公司内部引用了第三方库,按照依赖倒置的原则,建议封装一层之后放到Basic Specs供业务方使用。
又来到了一年一度的QA环节。
Q:如何把握组件拆分粒度?
A:没有一个可衡量的标准,需要结合具体业务场景,那些复用性高、功能相对独立就可以考虑做拆分。还有需要注意的是,组件拆分不一定要抽离成pod库,可以将有一定特性的 一组通用组件 打成一个pod库(姑且定义成CommonUIKit)。我们知道pod库最终都是生成静态库引用到主工程的,也就是最终都会经过链接的过程,pod库过多会带来一定的App启动性能开销,其次pod库过多也会导致pod管理混乱的问题。
Q:比如一个很小的功能,就一个弹框我需要去做解耦么,我抽成pod库别人直接引用不就得了? A:在回答之前,我们先思考两个问题。弹框组件未来变动可能性有多大?你设计的Api是否合理,是否能够满足未来产品的需求?第二个问题,解耦带来的益处能够cover住这些可能的变动带来的弊端?想清楚这两个问题,我们就知道设计一个组件是否需要做解耦,是否需要用中间服务去除依赖了。
解决横向依赖
-
通用组件层的横向依赖。
通过上图可以发现,首页组件实际只是获取了登录态,但登录模块没有提供对应服务,则只能通过引用头文件的方式把该组件import进来,两者耦合在一起。
利用中间件的概念,我们可以在两个模块之间建立一个 服务层 ,专门用来进行模块间的数据通信,或者非界面跳转的小粒度组件的数据通信。这样就很好的解决了两个组件的横向依赖问题。
-
业务模块间的横向依赖。
这里主要说的是那些业务功能独立、业务线之间的横向依赖。举例说明,首页模块可能带有业务A、业务B、业务C的入口,如果没有做组件化,则首页模块连同A、B、C业务都耦合在一起。这里推荐几个比较比较常用的路由解决方案。
JLRoutes-URL routing library for iOS with a simple block-based API。
BeeHive-iOS的App模块化编程的框架实现方案,吸收了Spring框架Service的理念来实现模块间的API耦合。
CTMediator-基于Mediator模式和Target-Action模式。
Q:我该如何设计一个路由,用于模块间的跳转?
A:设计路由需要遵循几个原则。
第一,便于集成,最小的改动即可实现一个路由。
第二,最大限度把参数正确性校验提前,能在编译时校验就不要在运行时校验。
第三,尽可能的支持多种注册方式,静态注册、动态注册、服务配置等。
未完待续
文章首发GitHub作者:一线搬砖工人
链接:https://www.jianshu.com/p/ba08804ce056
以上所述就是小编给大家介绍的《一名一线开发对于App架构和组件化的思考》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 组件化架构漫谈
- Android组件化入门:一步步搭建组件化架构
- iOS组件化及架构设计
- iOS组件化开发架构设计思考(初版)
- 从智行 Android 项目看组件化架构实践
- Android 架构设计:MVC、MVP、MVVM和组件化
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Linux设备驱动程序
科波特 / 魏永明、耿岳、钟书毅 / 中国电力出版社 / 2006-1-1 / 69.00元
本书是经典著作《Linux设备驱动程序》的第三版。如果您希望在Linux操作系统上支持计算机外部设备,或者在Linux上运行新的硬件,或者只是希望一般性地了解Linux内核的编程,就一定要阅读本书。本书描述了如何针对各种设备编写驱动程序,而在过去,这些内容仅仅以口头形式交流,或者零星出现在神秘的代码注释中。 本书的作者均是Linux社区的领导者。Jonathan Corbet虽不是专职的内核......一起来看看 《Linux设备驱动程序》 这本书的介绍吧!