架构与设计思想

设计的目的

一般在程序编程,方案设计,以至系统架构的时候,往往会考虑以下几个方面的折衷,然后应用某类”设计模式”或者”架构思想”:

  • 初次开发效率(设计直观性,时间成本)
  • 可维护性,可读性(scope不变的情况下,是否改动频繁)
  • 可扩展性(后续scope会否增大,甚至是否可能要支持进一步拆分以及并行多人员开发)
  • 可扩容性(流量压力是否可能增大)
  • 鲁棒性(抗regression,抗edge case)
  • 可用性
  • 实时性
  • 一致性
  • 对快速发布的要求

以上是直接的目标,有一些细节层面的表现:

  • 代码或者架构是否足够清晰,是否有过度冗余(冗余其实不一定有问题)
  • 耦合是否松散
  • 内聚性如何,是否自恰,完备
  • 是否易于改动或者扩展

有一句 一般性正确 的话叫做”高内聚,低耦合,易扩展,拥抱变化“,并不是这样的设计就一定对,只不过可能适用于大多数场景。
然后要特别注意避免“过度设计或者过度优化”。
而对于大多数互联网应用而言,目标往往是为了能实现敏捷开发、部署、迭代

不同的设计思想

再后面因为对目标优先级的不同,可延伸出不同的”模式”或者”思想”,比如:

  • 面向过程 vs 面向对象 vs 面向组件 vs 函数式
  • 巨型单体 vs 面向服务 vs 微服务 vs 分布式高并发设计
  • 各种设计模式
  • 继承 vs 组合
  • 开放 vs 封闭 (对扩展开放,对修改封闭)
  • 约定 vs 配置

总体而言,没有绝对的”好”与”坏”,主要还是要看应用场景和目标优先级,来选择适合的方案。

以下几个具体的”模式”或者”思想”。

面向对象

这其实也像是一 世界观,如何在程序的世界里“认知和抽象现实世界“。
主要是应用封装,继承,多态。
有以下几个优势:

  • 内聚性较好,对象掌控自己的核心功能模块(“封装”)
  • 耦合规则清晰,对象的边界清晰(“封装”,世界观是由不同的对象建立起来的)
  • 以上可以提供不错的扩展性,和鲁棒性
  • 规避冗余,方便重用(“继承”,“多态”)
微服务

一般来说,应用微服务是为了 处理复杂场景 的,采用的原因往往是 1)业务非常复杂,且规模很大 2)开发的人员和团队非常多。
能大幅提高并行开发能力,但对基础架构要求较高,可用性也是个挑战
它的优势:

  • 边界清晰,单个服务很容易开发、理解和维护(但设计不好的情况下,整体上可能是比较能理解甚至混乱的)
  • 方便控制regression,往往一个功能的改动只会影响一个具体的服务。
  • 部署速度较快,每个服务可以单独发布,且体量较小。
  • 每个服务可以独立扩展。计算密集型,IO密集型的服务可以有效分离,更方便科学扩展。
    一些挑战:
  • 如前面所言,整体的复杂必不一定下降,甚至上升。
  • 分布式系统对基础架构(PaaS)的要求较大,不然会大幅增加基础架构的维护成本。
  • 如果依赖性比较复杂,可用性不易控制。

关于扩展:

  • 水平扩展(复制实例,应用负载均衡)
  • 业务拆分(不同的业务,不同的计算、吞吐属性)
  • 数据分区(不同地域)

参考: