从 0 开始学架构
李运华
网名“华仔”,前阿里资深技术专家(P9)
152571 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 66 讲
结束语 (1讲)
结课测试 (1讲)
从 0 开始学架构
15
15
1.0x
00:00/00:00
登录|注册

06 | 复杂度来源:可扩展性

规则引擎和设计模式
抽象层和实现层的关系
变化层和稳定层的接口设计
变化层和稳定层的拆分
1写2抄3重构原则
方案二:抽象层和实现层
方案一:变化层和稳定层
2年法则
不同行业的变化速度
可扩展性
高可用
高性能
应对变化
预测变化
复杂度来源之一:可扩展性
可扩展性

该思维导图由 AI 生成,仅供参考

你好,我是华仔。复杂度来源前面已经讲了高性能和高可用,今天我们来聊聊可扩展性。
可扩展性是指,系统为了应对将来需求变化而提供的一种扩展能力,当有新的需求出现时,系统不需要或者仅需要少量修改就可以支持,无须整个系统重构或者重建。
由于软件系统固有的多变性,新的需求总会不断提出来,因此可扩展性显得尤其重要。在软件开发领域,面向对象思想的提出,就是为了解决可扩展性带来的问题;后来的设计模式,更是将可扩展性做到了极致。得益于设计模式的巨大影响力,几乎所有的技术人员对于可扩展性都特别重视。
设计具备良好可扩展性的系统,有两个基本条件:
正确预测变化
完美应对变化
但要达成这两个条件,本身也是一件复杂的事情,我来具体分析一下。

预测变化

软件系统与硬件或者建筑相比,有一个很大的差异:软件系统在发布后,还可以不断地修改和演进。
这就意味着不断有新的需求需要实现
如果新需求能够少改代码甚至不改代码就可以实现,那当然是皆大欢喜的,否则来一个需求就要求系统大改一次,成本会非常高,程序员心里也不爽(改来改去),产品经理也不爽(做得那么慢),老板也不爽(那么多人就只能干这么点事)。
因此作为架构师,我们总是试图去预测所有的变化,然后设计完美的方案来应对。当下一次需求真正来临时,架构师可以自豪地说:“这个我当时已经预测到了,架构已经完美地支持,只需要一两天工作量就可以了!”
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文探讨了软件系统的可扩展性,着重从预测变化和应对变化两个方面展开讨论。在预测变化方面,提出了“2年法则”来平衡可扩展性和实际需求之间的关系。而在应对变化方面,通过“变化层”和“稳定层”来隔离变化,同时介绍了“抽象层”和“实现层”以及“1写2抄3重构”原则。文章指出,软件系统的可扩展性是一个复杂而重要的问题,需要架构师在实践中不断寻找平衡点。总的来说,本文深入探讨了软件系统可扩展性的复杂性和实现方法,为读者提供了深入的技术思考和应对变化的实践建议。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《从 0 开始学架构》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(130)

  • 最新
  • 精选
  • 憶海拾貝
    设计模式的核心就是,封装变化,隔离可变性

    作者回复: 这是设计模式的核心思想,能理解到这点比背住23个模式更重要

    2018-05-11
    4
    208
  • 约书亚
    我平时工作中更多提醒自己压抑一下想预测各种需求变化的欲望。因为之前总是过度设计。压抑并不是说不去考虑各种变化,而恰恰需要把可能性大的变化点一一罗列出来,分维度打分,维度包括 可能性大小?长期还是短期会变化?如果发生变化,目前的组织和系统要花多大成本适应变化。这些变化正是李老师之前说过的各种复杂度上的变化,比如用户量激增带来的性能要求。此外还包括一个业务功能逻辑上的变化。 在经过上面分析后往往会给出“上中下”策的设计方案,下策一般考虑的变化少,短视,但迅速,修改小,立竿见影。上策一般看重远期,但成本高很高,也很可能预测不中。 最后还要分析,如果决定采用下中策,如果预测的变化发生了,系统修改为中上策的代价有多大,有些代价几乎是无穷大的,比如必须中断服务进行升级。如果代价小,那可以放心采用下策或中策。如果答案是否,可上策当前的代价又真的不可接受,那又要返回头重新分析了 实践发现这个方法挺好用,尤其当有人来咨询架构方案时,往往对给出的结果比较满意

    作者回复: 挺实用的方法,架构设计原则部分会讲到

    2018-05-10
    6
    136
  • Jaime
    曾经在游戏中使用过工厂模式和状态模式,但交个另外一个人维护了一个月,我回头去看,代码已经没办法入眼😅😅😅。虽然说设计模式确实是程序员的基本功,但其实很多程序员也不是很明白设计模式的。对于现在来说,我比较喜欢的做法就是先分层,层与层之间用消息解耦,在层内部的实现我会分模块出来,遵守单一职责原则。同时会积极跟业务部门沟通,预测一下下一步的方向。虽然不是每次都准确,但也大概做到心中有数,对于现在的系统也有个预估。这几年的编程经验给了我一些启发,一定不要过分设计,首先要能正确工作的软件是最重要的。

    作者回复: 符合实际情况,分层最有用,代码中用设计模式,如果后面接手的人不懂或者理解不到位,最后改的代码简直没法理解,还不如面向过程😂

    2018-05-10
    5
    67
  • Mark Yao
    说说我们的消息系统,原始需求是用户操作业务后给用户手机短信提醒,设计初衷考虑到可能涉及到多家第三方短信服务商。我们统一定义发送短信接口,定义实时和定时发送方式,在内容形式定义模版接口接受不通形式自定义模版的内容,后来把短信定义为消息中的一种,如微信、短信、站内消息、app push 都为消息,又抽象出来消息接口,消息开发中使用多种设计模式。最后发现就就一直使用短信服务。我困惑地方,扩展性需要在什么时候做,做到什么程度呢?

    作者回复: 我的经验供参考:设计的时候考虑可扩展性,但如果评估后发现可扩展性设计的代价太大,那就暂时不做,等到真的有需求时再重构。 过早考虑可扩展性,很多通用性和抽象都是推测的,等到真的要落地了,很可能发现事实并非如此,这就是预测是错误的。 回到你的案例,一般来说,短信本身会考虑可扩展性,例如联通的短信接口和电信的不同,这种可扩展性是要一开始就设计的,但短信和微信,看起来都是消息,实际上差异非常大,可扩展性设计想兼容这两种方式,方案比较复杂,可能看起来有点不伦不类

    2018-05-10
    5
    41
  • 带刺的温柔
    厉害了程序员都想要开发一个完美的灵活可扩展的系统永无止境,而往往陷入过度设计的泥潭,最后累的要死得到的可能是貌似完美符合了扩展性但是非常不好用甚至有点画蛇添足的感觉。觉得扩展性不是一触而就的也不是一成不变的它是一它是不断改进的过程,不变的是满足需求是底线在追求扩展性的路上把风险控制在最低。我在兼容简单与扩展性上我觉得一定的冗余是个不错的选择,老师你觉得呢

    作者回复: 非常正确,一定的冗余和浪费,能够大大减少方案的复杂度

    2018-05-11
    14
  • 武洪凯
    老师能不能推荐一些构架的书,中文的英文的都可以。课程讲的很好,不过很多细节深扣的话感觉还要继续看书。

    作者回复: 深扣细节的话,就直接奔着具体某个系统或者专题,例如kafka或者缓存,这样找书就很容易了

    2018-06-26
    11
  • 明翼
    设计模式里面的依赖倒置原则,上层不依赖下层,下层也不依赖上层,两者都依赖于抽象,抽象是稳定的,上层和下层都是可扩展的,相当于文章说的一个稳定层抽象,两个变化层…

    作者回复: 纠正一下:SOLID原则不是设计模式里面的,而是对象和接口的设计原则。 依赖倒置的难点就在于稳定层的设计,实践中稳定层也难以保证稳定

    2018-05-10
    9
  • zhou
    老师你讲的看起来有点吃力,能否推荐几本书让我先入个门

    作者回复: 专栏已经是我综合自己的经验,结合看了很多架构设计的书籍整出来的,如果专栏看的有点吃力,那看其它书会更吃力。 可以说说你吃力的点,看看能不能帮到你

    2018-06-14
    8
  • 孙振超
    之前看过一篇介绍架构的博文,里面提到一个观点:衡量架构的好坏是变更的成本。扩展性的好坏很依赖于设计人员对问题的抽象能力,如同文中所描述的把系统分为稳定层和抽象层两部分,就是对问题进行了抽象。具体而言,在设计上经常采用的方法是模板+接口,将具体的业务逻辑抽象为固定的几个步骤,每一个步骤是一个接口,而后根据不同的对应的参数动态选择不同的实现,这样当已有的业务发生变更时,只需要调整相应的逻辑即可,做好关注点分离,面对新增的业务逻辑和形态,添加对应的实现即可,无需修改已有的内容。 另外就是利用动态修改能力(比如java中无需重启服务修改某一个属性的值)来应对业务变动,提升扩展性

    作者回复: 将业务逻辑抽象为固定的步骤,适合业务已经比较成熟了,例如nginx将http的处理步骤抽象为大概10个阶段,如果是创新业务,这样做比较难

    2018-05-26
    8
  • escray
    老师在留言里面提到,“设计的时候考虑可扩展性,但是如果代价比较大,就展示不做,有需要时再重构”,这个比较实用。 之前做过的系统对于可扩展没有什么要求,实在不行的时候,就会考虑推到重来。 可扩展性并不想前面提到的高性能和高可用那么容易衡量,因为扩展的可能性还是要小一些,或者说可扩展性并不是特别的明显。 按照专栏里面的说法,设计模式好像更多的是考虑可扩展性,感觉上似乎对于高性能和高可用意义不大。但是反过来,对于普通的应用开发者来说,是不是遇到扩展性问题(或者需求变化)的可能性要远大于高性能或者高可用?

    作者回复: 是的,普通应用开发者更多是代码层面的可扩展性,而不是架构层面的可扩展性

    2020-09-03
    6
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部