UIDesigner是腾讯用户研究与体验设计部(CDC)设计研发的一款设计类软件,打造一款可以让设计师统一平台和团队协作的平台型设计工具,经过1.0和2.0版本的经验沉淀,我们决定对3.0版本进行全新的架构设计。
开发一个软件系统,前期的架构设计承载着整个软件的设计思想和关键决策,可以说是重中之重。
根据软件架构设计思想,关注分割和交互,好的架构必须使每个关注点相互分离。我们进行了最基本的需求分析,得出两个关注点:一是工具,二是设计绘图,关系如图1所示。
得到最基本的两个关注点后,接着将提取关键需求(包括:关键功能需求、关键质量需求和关键商业需求),根据两个关注点进行架构的细化设计。
一、关注点——工具
这里我们结合UIDesigner的实际需求,提取出属于“工具”范畴的关键功能需求、关键质量需求和关键商业需求。
首先,“工具”的关键功能需求,必须包括:磁盘文件读写、异常捕捉、日志记录、安全性管理;非工具所必须,但是UIDesigner本身所要求的,包括:配置管理、缓存管理、线程服务、服务器和客户端通讯管理、国际化服务。
其次,“工具”的关键质量需求,质量需求包括开发期质量需求和运行期质量需求两部分,经过分析和权衡,UIDesigner的性能主要取决于设计绘图,而稳定性、可扩展性和可维护性才是决定“工具”本身发展的质量需求,因此,对“工具”的质量需求设计将以稳定性、可扩展性和可维护性为主。
最后,“工具”的关键商业需求,因为UIDesigner本身并没有很复杂的业务需求,因此关键商业需求是在设计流程的优化和规范上得到体现,这方面的设计已经属于高层模块和使用流程的设计,对架构的影响非常小,可以暂时性的忽略。
经过关键需求的提取,我们得到了“工具”的设计目标——可以提供通用功能(关键功能需求)的高稳定性、扩展性和维护性的客户端应用。根据此目标,我们采取了DI(Dependency-Injection)和MVP(Model-View-Presenter)结合的架构,概念架构设计如图2所示。
1、将上层功能进行模块划分,每个模块内部都依赖于MVP架构,通过Model(继承至BaseModel)定义和注册模块,通过观察者模式,每个模块的View都可以通过Presenter(继承至BasePresenter)进行消息的发布和订阅,进行模块间的通信和交互。
2、定义集成了关键功能需求的PlatformService,并在BasePresenter中提供PlatformService的服务调用,这样每个功能模块都可以使用通用的关键功能。
3、为PlatformService的服务定义接口,根据关键功能需求,得到多个服务的接口,将定义和实现相分离,实现部分作为一个特殊的功能模块(核心模块,必须存在),集成到系统本身,方便前期的验证和后期的扩展和维护。 属于“工具”这个关注点的架构就已经设计好了,具体的上层功能模块将在后续的开发中,根据需求一个一个模块的来完成,每个模块之间不会有任何依赖关系(开发时),缺少某个或多个功能模块的时候,软件依然可以稳定的运行起来。
二、关注点——设计绘图
UIDesigner是为设计师打造的设计工具,其最核心的功能需求当然就是设计绘图了,这一块也是变化最多的。根据隔离变化点的原则,我们将这一块设计为绘制引擎框架,通过框架,为“工具”部分提供绘制相关的支持。
我们对绘制引擎框架进行细化分割,分离出三个关注点:图元、画板、辅助组件。
首先,图元是可以通过定义进而展示出自身的基础元件,由基础属性和基础绘制接口两部分组成,其中基础绘制接口的定义和实现分离,这样可以方便后期的扩展,特别是在性能改进方面发挥重要作用。概念设计如图3所示。
其次,画板作为各种图元集合的容器,支持对各种图元的操控和定位,被分为三层:点击测试层、图元设计器管理层和图元绘制层。概念设计如图4所示。
最后,辅助组件分为标尺、辅助线、全局缩略图、遮罩装饰器和自动对齐线等,这些辅助组件都依赖于画板而存在。
三、架构验证和后续开发
在概念架构设计出来后,我们对核心进行了进一步的细化设计,然后对设计的架构进行验证。为了达到敏捷开发和节省时间成本,结合设计的架构,我们最终选择了垂直演进型原型进行架构的验证和后续开发。
因为架构本身是基于DI(Dependency-Injection),是非常符合垂直架构设计的一种架构模式,因此我们搭建了简单的基础核心(只有核心模块,没有其他业务流程功能模块)和简易的绘制引擎框架实现了原型。
通过对原型的测试和验证,确定此架构满足我们的预期。在此原型的基础上,继续完善核心和绘制引擎框架,并且规划后续的业务功能,根据业务功能插件,可以合理的安排项目进度,最终按照计划顺利完成开发和测试。
四、后期仍待改进的一些地方