系统设计
系统设计是将一个实际问题转换成相应解决方案的主动过程,是解决办法的描述。在通用的软件工程过程模型中,需求分析完成后的第一步就是系统设计,一个项目最终的稳定性、易用性在很大程度上取决于系统设计这一步。
Beeshell 组件库是为了更加快速的搭建移动端应用,为业务开发提供基础技术支持,大幅提升开发人效。然而,面对不同的业务方、不同的功能需求、不同的 UI 规范与交互方式,如何有效的兼顾所有的需求?这对系统设计提出了更高的要求,下面以抽象层次逐层降低的方式来详细介绍 Beeshell 的系统设计。
框架设计
React Native 的出现为移动端开发提供了新的选择,React Native 有比原生开发更高的开发效率,比 HTML5、Hybrid 更好的性能,从而脱颖而出,使得越来越多的开发者开始学习和使用 React Native。
Beeshell 组件库基于 React Native,向下通过 React Native 与 iOS、Android 平台进行系统层面的交互,向上提供开发者友好的统一接口,抹平平台差异,为用户开发业务功能提供服务支持。Beeshell 扮演了一个中间者的角色,保证了移动端应用基础功能的稳定性、易用性。
框架设计确定了 Beeshell 的系统边界,指明了包含的功能与不包含的功能之间的界限。明确了系统边界,我们才能继续进行下面的分析、设计等工作。
设计原则
在进行组件库的详细设计之前,我们提出了几个设计原则:
- JS 实现优先。使用 JS 来实现功能有几个好处:跨平台通用性、更高的开发效率、更低的学习和使用成本。
- 继承与组合灵活运用。继承和组合都是实现功能复用、代码复用的有效的设计技巧,都是设计模式中的基础结构。继承允许子类覆盖重写父类的实现细节,父类的实现对于子类是可见的,一般称之为“白盒复用”,对这对组件的定制化扩展很有效,Beeshell 强大的定制化扩展的能力就是基于继承实现;组合是 React 推荐的方式,React 组件具有强大的组合模型,整体类和部分类之间不会去关心各自的实现细节,它们之间的实现细节是不可见的,一般称之为“黑盒复用”,Beeshell 也广泛使用了组合,基于通用型的组件组合出更加丰富、强大、个性化的功能,在一定程度上提高了 Beeshell 的定制化的能力。
- 低耦合、高内聚。一个 Beeshell 组件本质上就是一个 React 组件,React 组件之间主要通过 Props 通信,这属于数据耦合,相比于内容耦合、控制耦合等其他耦合方式,数据耦合是耦合程度最低的一种,受益于 React 的实现,Beeshell 组件低耦合是自然而然的;而要做的高内聚,则对组件的编码实现方式有一定的要求,我们推行内聚方式中内聚程度比较高的交互内聚和顺序内聚。使用单一数据源,使各个元素操作相同的数据结构,实现交互内聚。使用不可变数据更新的方式,上一个环节的输出是下一个环节的输入,像流水线一样处理逻辑,这便是顺序内聚。
方案设计
整体上使用 JS 作为统一入口,多层封装隐藏实现细节,抹平 JS 与 Native、iOS 平台与 Android 平台的差异,开箱即用,降低了用户的学习和使用成本。局部上基于 React Native 的技术特点,分成 JS 组件部分和复合组件部分,两部分推行“松耦合”的开发模式,使得 Native 部分拥有替换变更的能力,提升组件库的灵活性。
复合组件部分可以直接暴露 JS 接口,如果有需要,也可以在 JS 组件部分进行定制化封装。我们尽量保证 Native 部分功能的原子性、简洁性,有任何定制化需求都使用 JS 来统一实现,遵循 JS 实现优先的设计原则,保证跨平台通用的特性。下面分别介绍 JS 组件部分和复合组件部分的设计。
JS 组件部分设计
一个软件的设计分为三个设计层次:体系结构、代码设计和可执行设计。我们使用自上而下的方法,从体系结构开始进行 JS 组件部分的设计。
软件的体系结构的风格通常有 7 种:管道和过滤器,面向对象,隐式请求,层次化,知识库,解释程序和过程控制。
JS 组件部分使用了层次化的体系结构风格,整体分成三层:基础工具、通用组件、扩展组件,从上到下通用性逐渐减弱、定制化逐渐增强,功能渐进式增强,通过分层设计,各层各司其职,兼顾通用性和定制化。
- 基础工具(common):最基础的、通用的部分,包含 JS Utils、动画定义、UI 规范等。
- 通用组件(components):把功能相似的组件进行归类,整理成一个个系列,每个系列内部使用继承的方式实现,层层依赖,功能渐进式增强,该部分专注通用性,不考虑定制化需求,保证代码的简洁性。同时,在比较细的粒度对组件进行拆分,提供了良好的可扩展性。
- 扩展组件(modules):是对通用组件的继承扩展、组合应用,该部分专注定制化,在最大程度上满足业务上的需求,通用性较低。
我们扩展组件部分会提供大量的定制化组件,如果仍然不能满足需求,用户就可以借鉴扩展组件的实现,根据自己业务需求,在某一继承层级上继承通用组件,自行进行定制化扩展,这点充分体现了 Beeshell 定制化的能力。
复合组件部分设计
既然是 React Native 组件库当然少不了 Native 部分,复合组件包含 Native 的功能,Beeshell 组件库已经完成了 Native 部分的集成方案与规范,有良好的开发与使用体验,可以不断的集成原生功能。
复合组件部分通过 JS 封装接口,保证了跨平台,Native 部分主要分成 Native Bridge 和纯 Native 两大部分,Bridge 是针对 React Native 的封装,必须在组件库中实现,而纯 Native 部分则可以通过 Pods/Gradle 依赖三方实现,有效的吸收利用原生开发的技术积累。