我争取用3000字就讲清楚架构!

847 阅读7分钟

架构是什么?

我们写代码时,总能听说一个名词: 架构

架构是什么呢?简而言之:架构 = 模块结构+运行机制

我们从一个简单的案例说起。

一、架构起源

在没有 架构 之前,编程就类似写任务清单,挨个给计算机下达一系列的指令。

比如买菜的指令如下:

  1. 先去楼下小卖部打瓶酱油。
  2. 然后到菜市场买一个土豆。
  3. 如果看到西瓜,就买两个。

PS: 用专业术语来说,这叫做 面向过程

而随着时间的推移,我们有了更复杂的需求。

比如一个贪吃蛇游戏的任务清单如下:

  1. 初始化游戏:

    1. 创建蛇的初始位置和长度。
    2. 在游戏区域生成初始食物。
  2. 处理用户输入:

    1. 监听用户按键,包括上、下、左、右箭头键。
    2. 根据按键调整蛇的移动方向。
  3. 更新蛇的位置:

    1. 根据当前移动方向,更新蛇头的位置。
    2. 更新蛇身体的位置。
  4. 检测碰撞:

    1. 检测蛇头是否与食物位置重合,如果是,增加蛇的长度,并在新位置生成食物。
    2. 检测蛇头是否与蛇身体碰撞,如果是,游戏结束。
    3. 检测蛇头是否与墙壁碰撞,如果是,游戏结束。
  5. 更新游戏状态:

    1. 记录游戏分数。
    2. 更新游戏速度(随着时间的推移可以加快)。
  6. 绘制游戏界面:

    1. 在屏幕上绘制蛇的位置和形状。
    2. 绘制食物的位置。
    3. 显示当前分数和游戏状态
  7. 游戏结束处理:

    1. 显示游戏结束画面。
    2. 提供重新开始游戏的选项。

而当需求变更时,复杂的任务清单往往很难维护迭代。

比如我们想给食物加点特殊效果——某些食物吃了会加速。

此时我们就不得不去重新修改刚才的复杂逻辑。

为了更好的迭代,于是我们想到了分而治之。

我们可以把整个游戏逻辑可以拆成四个模块

  • Game 类:
    • 负责游戏的整体逻辑和流程控制。
    • 包含 Snake 对象和 Food 对象。
    • 处理用户输入、更新游戏状态、绘制游戏界面等。
  • Snake 类:
    • 表示贪吃蛇对象。
    • 包含蛇的位置、长度、移动方向等属性。
    • 提供移动、吃食物、检测碰撞等方法。
  • Food 类:
    • 表示食物对象。
    • 包含食物的位置、效果等属性。
    • 提供生成新的位置等方法。
  • SpeedFood 类:
    • 继承自Food类,为接触到的贪吃蛇提供速度。

PS:这也叫 面向对象 设计。

并提供一些 运行机制,把模块组合搭配起来:

  • Game 类生成食物时,随机生成 Food 及其子类( SpeedFood 类)。
  • SpeedFood 类接触贪吃蛇后,可以加速贪吃蛇。

比如,当需要给食物添加新功能时,我们只需从Food类派生新的"子类"即可。

上诉分治规划模块结构运行机制的过程,便是 架构设计

分治的结果,便是架构

有了这样的模块结构运行机制,我们便可以更轻松的迭代需求。

有了架构设计之后,我们便可以更轻松的迭代维护我们的项目了。

二、架构概念

我们总结一下上诉案例,我们了解了什么?

  1. 架构 = 模块结构 + 运行机制

  2. 架构就是为了让我们更方便的迭代项目。

顺便一提 : 模块结构 与内聚相关,运行机制 与耦合相关。

你所了解的所有架构几乎都可以套用这个公式。 比如上诉"贪吃蛇"游戏的架构可以这么描述:

  1. 模块结构 如下
    1. 游戏世界模块
    2. 贪吃蛇模块
    3. 食物模块
  2. 运行机制 如下
    1. “游戏世界” 创建并控制“贪吃蛇”和“食物”。
    2. “贪吃蛇” 碰撞 “食物” 获得加速。

比如大家耳熟能详的 MVC 架构就可以这么描述:

  1. 模块结构 如下
    1. 模型层
    2. 视图层:管理页面UI
    3. 控制器
  2. 运行机制 如下
    1. 模型层 管理数据模型,提供API。
    2. 视图层 管理页面UI,提供渲染函数。
    3. 控制器 处理接口请求,实现业务逻辑,串联模型视图

小问题:你能用该公式说明你手上项目的架构吗?

接着我们不难发现,软件开发是一项工程活动。

假如我们想让贪吃蛇更好玩,比如:

  • 我们想加入障碍物和陷阱,让游戏世界更加丰富。
  • 我们想加入更多种类的贪吃蛇,每种贪吃蛇都有不同的技能。

迭代过程中,我们肯定会发现一些问题,比如:

  1. 测试成本水涨船高。
  2. 手动发布太麻烦了。
  3. 发布后出现BUG不好定位。

而随着项目的壮大,我们可能会扩大我们的团队,又带来了新的问题,比如:

  1. 成员能力问题,理解不了架构,开发适得其反。
  2. 代码冲突问题,人多了就容易冲突。
  3. 项目管理问题,老是延期。

我们发现,我们的架构设计还需要考虑整个软件工程

要解决这些问题,我们不能仅仅只考虑代码上的设计,而是要综合整个团队所有成员来考虑。

于是我们在代码上加入了更多模块:

  1. 单元测试模块:提高测试效率
  2. 自动发布模块:提高发布质效
  3. 日志监控模块:提高运营效率
  4. 版本管理模块:解决代码冲突

于是团队上我们又引入了更多的机制。

  1. 技术分享:提高大家能力
  2. 迭代规范:帮助减少冲突
  3. 周会晨会:及时发现问题

三、架构作用

不难发现,架构的首要任务就是实现系统目标

为了实现系统目标,我们发现了一些复杂问题。

然后我们用规划模块 + 设计机制 的方式去拆解复杂问题。

把复杂的问题简单化,把抽象的系统给具体化。

把复杂的一大步,拆解成简单的一小步。

在代码逻辑上,更好维护迭代

我们把"复杂的任务清单",转化成更简单的"模块结构"。

我们把"在任务清单中插入逻辑"这一复杂任务,转化成了在"食物类下添加方法"这一简单任务。

我们的架构设计让我们的代码更好迭代、更好测试。

降低了开发成本,提高了开发效率,提高了项目质量。

在软件工程上,更好协作生产

也是依次发现问题分析问题,然后把大问题拆解成小问题,把抽象的问题拆解成具体的问题。

我们的架构设计让我们的软件开发更加顺利、更加稳定。

降低了开发成本,提高了开发效率、提高了项目质量。

总的来说

架构其实就是通过拆分模块设计机制的办法,用更低的成本、更高的效率、更高的质量来完成目标

稍做延展:

架构设计也不仅仅只是针对软件开发。 有系统的地方就有架构,比如咱们人体的消化系统,比如整个生态系统,无不涉及一定的架构设计。

后续章节咱们再来探讨其中哲学。


我是尘码,欢迎关注我的公众号:尘码的划水工坊