Day 31: 【全系列终】架构考古学

Appendix: 架构考古学

联盟会计系统

  • 简述
    1960 年代,很简单的 CRUD 记帐系统,由电晶体 & 部分真空管所组成的超大电脑 (GE datanet 30),需自干 OS & Driver
    https://ithelp.ithome.com.tw/upload/images/20211017/201386436T8EdLVeeH.png
  • KeyWords: Overlay System, Preemptively Swap, Supervisor, Interrupt
  • 小结
    • 划分 I/O 、储存装置、与主系统的 「边界」
    • 尽量将依赖反向,使依赖关系和控制流的方向不一致

笔者读完这节脑中马上浮现以前在恐龙本(作业系统)上看到的种种 Virtual Memory, Scheduler 相关概念... 不得不佩服原作者在那个年代竟然能自行领悟出这些东西... (跪)


雷射修阻

  • 简述
    在 M365 Computer 上开发的小型作业系统,为了雷射修阻及其相关应用程序所开发
  • KeyWords: Bootstrap Program, Master Operating Program (MOP), Isolation Layer, Data-Driven Language (DSL)
  • 小结
    • 没有强制划分开系统程序码和 DSL 编写的应用程序之间的边界。耦合处处可见 (再一次强调解耦的重要)

4-TEL

  • 简述
    每天晚上自动测试电话线路,并为所有需维修线路产生报告的晶片系统 (Firmware?)
  • KeyWords: 向量化、物件导向原则、UI & 业务规则分离、多型分派 (Polymorphic Dispatch)
  • 小结
    • 本章作者遇到一个痛点:每一次修正系统内的任何指令码,都需要重新更换全部 30 颗晶片 (成本极高)
    • 於是花一段时间想出「向量化」解决方案 (即,将程序划分为 32 个可独立编译的原始档、并做动态定址)
    • Plugin 架构:让晶片可独立部署 (Independently Deployable)、引入物件 (Objects) 的概念

服务区域的电脑

  • 简述
    • 修理工派遣系统 (承上一个专案)
  • KeyWords: Multiprocessing, Context Switch, Locks, Semaphores, Race Conditions, Clean Code
  • 小结

    「派遣决定的程序码是由非常聪明的人设计及编写的,但他却不是一位善於沟通者。编写程序码的过程是被这样描述的:『盯着天花板看三个星期,然後有两天程序码就从他身体的每个洞涌出来了 - 然後他就辞职了』」

    没有人理解这个程序码。最後,我们的管理阶层告诉我们,要锁住这些程序码并且永远不要修改它。程序码被正式宣告僵化了」

    「这次经验带给我的是,良好、整洁的程序码的价值


插曲: 学习「新」语言 — 「C」

「在 8085 Assembler 中写 Code 可一点都不好玩。我听说有一种在贝尔实验室大量使用的『新』语言。他们称它为『C』。我对这种语言的简单优雅感到震惊,它没有牺牲组合语言的能力,并使用更方便的语法来提供同等的能力。我变心了」

「现在唯一的问题是,面对一群组合语言程序设计师,如何说服他们应该使用 C 语言。但这是另一个噩梦般的故事......」


Basic Operating System and Scheduler (BOSS)

  • 简述
    • 作者用 C & Assembly 在 8085 平台上写出的任务切换器
  • KeyWords: Concurrent Tasks、Non-preemptive、Blocked、轮询 (Polling)
  • 小结
    • 该软件成为未来几年大量专案的基础

DLU/DRU

  • 简述
    • 加入远端连线功能的派遣系统,因应公司规模的扩张
    • DLU 的架构设计是基於资料流模型的
      每个任务都只专注在一个小工作,并透过一个伫列 (Queue) 将它传递给下一个任务。类似工厂的组装流水线 (Pipeline)
    • DRU 的架构设计则完全相反
      为每个终端机建立一个任务,没有 Queue、没有资料流。可类比成许多建造者,而每一个人都建造一个完整产品
  • 小结

    「当时我认为我的架构很优秀。当然,MIKE 认为他的比较好。当然最後,两个人都工作得很好。我意识到,软件架构可以大不相同但同样能发挥作用


Voice Response System (VRS)

  • 简述
    • 加入按键语音功能的故障定位系统
    • 采用了当时很潮的「新技术」:嵌入式 SQL (Embedded SQL)
      导致 Code 和 DB 操作密切耦合
    • 团队决定更换资料库供应商 (UNIFY --> SyBase)
      经过三个月的努力,决定放弃 (成本极高)。最後只能聘请第三方维护 UNIFY

      「当然,维护频率逐年上升」

  • 小结

    「这是我了解到『资料库』是该与『系统的整体业务目的』隔离的原因之一,也是我不喜欢强烈耦合到第三方软件系统的原因之一」


The Electronic Receptionist (ER)

  • 简述
    • 有史以来第一个语音邮件系统

      注: 我们的雇聘合约清楚表示,我们发明的任何东西都属於公司。我的老板告诉我:「你用一美元把它卖给了我」

    • 这个系统的架构如果在今天会被称之为以服务为导向的 (Service-Oriented)
    • 这款产品的市场行销并不理想。Teradyne 是一家销售「测试设备」的公司,而他们不了解如何打入「办公设备」的市场。经过两年的尝试,CEO 决定放弃

修复工派遣系统 (Craft Dispatch System)

  • 简述
    • 管理电话维修人员的系统
    • 在搭飞机时,作者发明了一个名为 Field Labled Data (FLD) 的方案,类似现在的 XML 或 JSON
    • 作者开始建立现在称之为微服务架构 的东西
      使用 XML 透过共享记忆体模拟通讯协定的微服务通讯 (1985 年)
  • 小结

    太阳底下没有新鲜事


Clear Communications

  • 简述
    • 1988 年,作者与原同事们离开了公司,成立的新创公司

    「这是一间新创公司,我们每周工作 70 到 80 个小时。我们有愿景。我们有动力。我们有意愿。我们有能力。我们有专业知识。我们拥有股权。我们梦想成为百万富翁。我们有够荒谬」

    「所以我们写程序。写程序。写程序。但三年後,我们没能做到的是卖出产品。市场对於我们的宏伟愿景并不特别感兴趣」

  • 小结
    • 没有结论。最後作者接到猎人头电话,被挖去大神 Grady Booch 的矽谷公司了

正好笔者学生时期有过几次参与创业团队的相关经验,实验室也曾与国内某量化交易新创公司密切合作过一小段时间。笔者看完这一节饶是特别有感触。也许正因为荒谬,所以才叫青春吧 (笑)


插曲: "Uncle Bob" 的由来

新创公司里有一名年轻研究员,给每个人都取了绰号。於是作者成为了 Uncle Bob

「最终,我意识到这是一个非常好的品牌」

插曲: 网路辩论

「当我学习时,也开始在 Netnews 上进行辩论。正是在这些辩论中,奠定了 SOLID 原则的基础。所有的辩论,甚至是某种意义上的,都引起了我的注意......」

最後,作者"疑似"因为在 Netnews 上的发言而被猎人头挖角

「热血充满了我的脸。我知道这代表什麽。这是 Grady Booch 的公司。在我面前,我看到了与 Grady Booch 合作的机会!」


ROSE

  • 简述
    • ROSE 是一个巨大的 C++ 程序。由层 (Layers) 组成
  • 检讨
    • 没有将依赖性指向高层级的策略
    • 没有建立一个真正的 Plugin 架构
    • 采用了「物件导向资料库」

      「但我们得到的是一个巨大的、缓慢的、侵入性的、昂贵的第三方框架。使我们的生活如同地狱一般」

  • 小结

    「实际上,最大的错误是 『过度架构 (Over-Architecture)』 。层数比我在这里描述的还要多许多,这大大降低了团队的生产力。整个工具被废弃了,取而代之的是一个小团队所编写的一个可爱小应用程序」

    「所以我了解到,伟大的架构有时会导致严重的失败。架构必须足够灵活以适应问题的规模」

P.S. 以中文来说,过度设计 (Over Design) 会有比较多的相关文章出现


建筑师登记测验

  • 简述
    • 1990 年代初期,作者已创业成为顾问,教导人们导入物件导向设计和架构
    • 第一个客户:Educational Testing Service (ETS)
    • ETS 已将问题分解成 18 个独立的测验,用於建筑师候选人的测验
      每一个测验都需要 1 个 GUI 程序及 1 个评分程序
    • 作者尝试一次为 36 个程序开发一个可复用框架
      於是和搭档两人花了一年开发出 45,000 行的框架程序码
  • 问题
    • 发现框架并不是特别可重用,有一些细微的摩擦,所以没办法发挥作用...
    • 计画表拖延了将近一年的时间
  • 小结
    • 於是作者重新开始,把旧框架放在一旁,开始同时写 4 个新的小测验,交付後再接着开发 4 支测验

    「我们学到了一个很好的教训:在第一次创造可重用的框架之前,你无法创造可重用的框架。要把它与几个可重用的应用程序一起建置」


全书完

「我希望的是,你会喜欢我在回忆之路上这次小小的旅行;并且一路上你可以学到一些东西」

「当然,这只是部分历史。我还经历了许多其他的专案。而我有意地将历史停止在1990年代初期 - 因为我还有另外一本书是用来描述1990年代後期的事件...」

取自: Clean Architecture (p.305)

P.S. 读者们是否注意到,本书几乎都没有提到 「敏捷 (Agile)」 这个关键字? 有兴趣的可自行参见 Robert C. Martin 的另一本书: 「无瑕的程序码 敏捷完整篇:物件导向原则、设计模式与C#实践」


Reference

  1. Clean Architecture: A Craftsman's Guide to Software Structure and Design
    寻找图片不小心查到的原文书...

後记

非常感谢各位读者追踪到此,这是我第一次参加铁人赛,也是第一次尝试在网路上将自己的心得整理成文章发表。真的从中获益良多...

这 30 天里,利用下班之余,读了近 800 页的内容。好几次加班回家後都只想躺平,但还是决定拿起书来翻阅,一边 Google 查阅补充资料。读完 Clean Code & Architecture 後,上班时间看着公司专案,慢慢地能理解那些以前似懂非懂的架构,甚至开始能从中嗅到程序码的气味 (Code Smell)、对於如何重构那些 "Legacy Code" 也开始有了点想法...

最大的感动大概就如铁人宣言里所述 「原来,我做得到」

有一点还是对读者感到很抱歉,到开赛的第二周以後其实文章的完成度就普遍下降很多,甚至到後期常常只有大小标题 + 引言而已。我不选择把各章节拆散到每一天、也不过度简化书中内容 (甚至会补充点图片或 Keywords),只希望能尽可能地将 Clean 系列书所提及的理念推广给各位读者们

接下来我预计会再花 30 天把未写完的内容补齐


<<:  铁人赛後感言 - 趣闻分享、30天回顾、四大收获、Canvas游戏後续发展

>>:  [Day31] 参数

MSP430 在 linux 上的环境设定

如果是 debian 了话,要在 /etc/apt/source.list 加入 deb http:...

低效率者如何规划学习时间?

哈哈 低效率者当然是在说我啦 (抱歉 文章分类只有技术可选择 这篇算是个人碎念日记啦) 进修时期总是...

Day 23 利用transformer自己实作一个翻译程序(五) Positional encoding

Positional encoding 在Day 13 Self-attention(七) Posi...

Day-6 Divide-and-Conquer-1 : merge sort

设计演算法 我们可以选择的演算法设计技术有很多种。插入排序使用了递增逼近(incremental a...

为了转生而点技能-Java难题纪录 (作业:染病接触之人员追踪链

前言: 本篇是参加学校开设的java资讯班的作业,由於对於笔者来说花蛮多时间的,所以想记录下来解题的...