codecamp

GoFrame 框架设计-统一框架设计

软件行业和建筑行业比较像,如果说我们的产品是一栋高楼大厦,那么程序代码就是建筑高楼的砖坯(我们每天的工作就像是在不停"搬砖")。如果说软件架构是高屋建瓴,那么程序代码是软件架构能够准确落地的关键构成。

image2021-3-23_13-49-12

程序代码如此重要,那么开发框架的重要性不言而喻。开发框架着力于代码层面,解决通用性的技术问题,目的是使得开发人员能够将精力关注于业务本身、辅助软件架构能够快速响应业务变化、提高软件的整体开发和维护效率。

本章节我们主要介绍统一开发框架建设的意义和必要性。

一、技术体系化

image2021-3-23_10-2-39

体系化更关注的是框架整体战斗力,而不是每个模块本身

框架体系化设计的显著特点:

  • 体系完善、组件丰富
  • 规范统一、风格一致
  • 统一抽象、设计严密
  • 执行高效,无重复逻辑

我们这里的体系化是指微观层面的代码开发框架自顶向下统一设计,使得整个框架的设计思想是一体的,而不是分散的。从技术上,解决一个具体的问题比较简单,开发一个特定的模块也比较容易,但是如何将共性的问题进行抽象沉淀、将各个独立的模块按照统一的设计思想组织协调,并产生强大的综合战斗力却不是一件简单的事情。这要求框架的设计师具备一定的技术底蕴、经验沉淀、格局和前瞻性,而不是眼界只关注于单个模块本身。

例如,我们即使没有开发过框架,但是应该或多或少使用过,知道一个框架至少会包含哪些模块。当我们需要写日志的时候,我们知道这种组件框架必定提供,那么会去框架中寻找并从官网获得使用帮助。当我们需要WebServer、数据库访问、模板引擎等等能力的时候,我们也可以预料得到,这种组件框架必定会有提供,那么也会去框架中寻找并从官网获得使用帮助。

再例如,我们在使用框架中各种模块的时候,虽然各个模块都是低耦合设计,按需引入使用,但是发现她们的配置管理方式都是一致的,都是结构化的配置管理对象,通过相同的配置管理模块,通过固定的配置项到配置对象属性映射规则,通过Get/Set开头的方法进行读取和设置(所有组件的参数获取和设置也是Get/Set开头的方法),全局的环境变量/启动参数设置也是类同的。这使得开发者能够快速认知到框架行为,做到快速接入、降低学习成本的目的。

再举个例子,在框架层面有一个非常棒的特性 - 调试模式,通过一定的环境变量或者启动参数打开,当开启调试模式时,各个模块核心的逻辑中会打印一些关键的日志信息,更有利于疑难问题的调试。并且调试模式默认关闭,不会影响执行性能。要做到这一点特性,只有自顶向下、统一化设计的框架才能做得到。目前Golang开发语言下仅​GoFrame​框架有此能力。

以上只是举的几点简单示例,如果您感兴趣,可以从框架中发现更多有趣的点。

最后,我们可以想一想,为什么我们潜意识中能够认知到框架的行为、框架能够提供极高的便捷性和极低的接入成本、框架模块在"高内聚,低耦合"的设计思想下却整体有着非常高的组织协调性。为什么会造成这样的现象?其实这就是框架采用体系化设计,还是"东拼西凑"封装 的差异。

举个比较贴切的比喻:​GoFrame​是一支纪律性、凝聚力和战斗力极强的"正规军",而不是"东拼西凑"的"散兵游勇"。

二、开发规范化

image2021-3-23_10-1-35

代码层面也是需要有一系列的开发规范,如基本的 代码结构、分层模型、封装设计等。统一的框架设计,将会使得所有的业务项目按照统一的代码设计进行编码,形成统一的开发规范。此外,框架的开发工具链也会使得开发规范更容易快速推广和落地实施。

三、组件统一化

image2021-3-23_9-59-26

这里的统一化有两层概念:

  • 多个相同功能组件统一为一个组件。
  • 多个不同功能组件统一到框架管理。

另一个痛点就是开发组件的百花齐放:

  • 实现相同功能逻辑的模块较多,选择成本增加
  • 项目依赖的模块过多,项目整体的稳定性会受到影响
  • 项目依赖的模块过多,项目无从下手是否应当升级这些模块版本
  • 各个模块孤立设计,单独看待每个模块可替换性很高,开发体系难以建立,开发规范难以统一

image2021-3-23_10-0-2

统一的开发框架才能将各个模块"各自为政"的状态收归到"统一管理":

  • 框架自顶向下设计,形成体系化、统一化的模块设计,更有利于开发规范化的实施
  • 框架核心维护较全面的通用基础模块,降低基础模块选择成本
  • 我们只需要维护一个统一的框架版本,而不是数十个模块版本
  • 我们只需要了解一个框架的内容变化,而不是数十个模块的内容变化
  • 升级的时候只需要升级一个框架版本,而不是数十个模块版本的升级
  • 统一的模块化设计可以减少不必要的逻辑实现,提高模块性能及易用性
  • 减轻开发人员的心智负担,提高模块可维护性,更容易保证各业务项目的模块版本一致性

四、版本一致性

版本一致性问题主要来源于项目依赖的模块过多、版本过多,造成版本很难以统一维护和升级。开发框架将模块统一化管理后,更容易保证项目模块的版本一致性。但是需要注意的是,这种一致性不是强一致性,只是降低了模块及版本的维护复杂度,但是不一致性的问题依然存在。

行业内也有一些版本强一致性的代码管理方案,例如采用​Monorepo​大仓的代码管理方式,却各有利弊,可自行了解,这里不赘述。

五、解决方案沉淀

image2021-3-23_10-52-50

基于统一的开发框架,更容易形成解决方案沉淀,企业与社区形成良性循环。解决方案的沉淀优先采用工具以及代码形式,而不是文档。

六、避免资源浪费

当每个团队都在试图自己创造轮子时,不仅无法形成统一的开发规范,而且会出现非常多的资源浪费。

这在Golang语言流行的初期,或者一个初创公司技术体系不完善的初期,现象比较明显。

resource-waste

让项目组把精力更多的投入到业务中,相信这是大多数技术公司的共识。使用统一的开发架构,可以把共性的技术问题提炼出来,并形成通用的解决方案。避免每个项目都独自去解决遇到的各种各样的技术难题,有效的把精力释放出来。


GoFrame 框架设计-模块化设计
GoFrame 工程开发设计-代码分层设计
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

GoFrame 核心组件

GoFrame 核心组件-数据库ORM

GoFrame 模块列表

GoFrame 模块列表-单元测试

GoFrame 模块列表-功能调试

GoFrame WEB服务开发

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }