读书笔记 -- 架构整洁之道 (Clean Architecture)

文章目录

  • 前言
  • 以业务为核心
  • SOLID设计原则
    • SRP: Single Responsibility Principle
    • OCP: Open-Closed Principle
    • LSP: Liskov Substitution Principle
    • ISP: Interface Segregation Principle
    • DIP: Dependency Inversion Principle

读的时间距离现在有点久,只能记住我的key takeaway了。其中第一点,也是最重要的一点就是,这是本好书,很推荐。

读完这本,然后再去看我之前推荐过的Team Topologies这本书(见博客如何打造高效的团队(一) - 团队架构);系统架构和团队架构是一体两面,用系统架构的眼光去架构团队,系统和团队相结合,打造高效能和可维护的系统和团队。

下面分享下我记住的要点:

前言

  1. 软件架构会提供两种价值:
    • 行为(Behavior):你的软件解决了什么问题、实现了什么功能。
    • 架构(Structure):你的软件是以什么方式组织在一起的,能不能灵活改变或者扩展行为。
  2. 走得快的唯一方式,就是走得好。确实有的情况因为市场机会需要简单粗糙快速出活,这是OK的,只要能意识到所有现在铺下的坑以后都是要指数级别偿还的,把这方面的代价加入你的考虑和计划中。
  3. 一个软件系统不管从什么方面来看,最昂贵的都是维护成本。所以不要光注意多快推出了一个新功能,推出不是终点,还要看看后续花了多少成本去维护和改进。
  4. 架构的目标就是减少搭建和维护系统所需要的资源。

以业务为核心

我个人认为这本书最重要的出发点就是业务,包括:

  • 业务的相关性:你的决定是不是和业务有关,你做决定的优先级是不是和业务的优先级一致,你做的事情是不是解决了业务要解决的问题。听起来很直观,但以我的观察很多工程师大部分时间里都会做着做着就忘了自己当初为了解决什么。架构都是为了业务服务的。
  • 业务的独立性:重新复习一遍康威定律,你的架构有没有限制你业务的独立性,如果有请慎重考虑。比如你在部门A,部门B自己使用的一套组件正好你也能用,就直接拿过来用上了,这样你就使你部门A的产品依赖于部门B了,但支持部门A并不见得在部门B的考虑之内,一个接口的改动可能就能让部门A的产品崩溃。
  • 业务边界:优秀的架构师都是擅长画边界的,哪些属于你管的可控的,哪些不属于你的不可控的;这个边界怎么交互等等。

从这三点衍生可以衍生出一些实践:

  • 不要看到重复就想合并:很多时候它们只是碰巧重复了。比如两个部门同时都有推出一个类似功能的计划,就算是这个功能现在看来全方位一致,但因为两个部门产品不同、用户不同、重点也不同,现在这个功能的重叠很可能就只是个现阶段的巧合。盲目合并会造成不必要的依赖。
  • 和业务最相关的应该越独立(越少或者不依赖于其它),与业务不相关的依赖于更相关的,而不是相反。比如你的核心业务模型,不应该依赖于某个具体的数据库或者某个具体的云服务。
  • 架构师做决定时先决定和业务最相关的,再决定不那么相关的。而且能不需要做决定的时候就先不要做决定,不要提前把路走死。比如用哪个数据库这种决定可能和业务没有最直接的关联,就等到不得不做决定的时候再去做。
  • 业务边界的划定要遵从康威定律。
  • 架构师设计的优先级应该是:先能用,再让它合理,最后优化

SOLID设计原则

SRP: Single Responsibility Principle

定义:A module should be responsible to one, and only one, actor.

注意这个原则的命名有很大的歧义,它指的不是说一个模块只能负责一件事情(这是一个代码设计的原则不是一个软件架构原则)。这里说的实际是:一个模块只对一种类型的actor负责。比如一个模块不能既面向广告主、又面向内部审核人员、又面向广告素材设计师;这样会造成业务上不必要的耦合。

OCP: Open-Closed Principle

定义:A software artifact should be open for extension but closed for modification.

这一条既是原则也是主要目的之一:软件架构应该易于通过扩展的方式定制和改变软件行为,而不需要对原有代码进行大规模的改动。比如你设计了一个做市软件,你要加入一个新的交易所,你应该通过简单的加入一个新的插件接入原有的软件来实现这个功能,而不需要(大规模的)修改原有的代码。

LSP: Liskov Substitution Principle

定义:What is wanted here is something like the following substitution property: If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T, the behaviour of P is unchanged when o1 is substituted for o2 then S is a subtype of T.

举例来说,比如多个Java模块实现同一个interface,多个Go structure实现同一个签名(interface),多个服务实现同一套REST API。使用者只依赖于这些抽象的接口定义,而不会依赖于具体的实现。这个原则可以被应用在系统边界的交互上。

ISP: Interface Segregation Principle

定义: No client should be forced to depend on methods it does not use.

依赖,且只依赖你所需要的。如果作为接口提供方应该能够让客户选择他们所需要的,而不需要依赖于他们所不需要的。比如你提供一个文字编辑工具包,客户如果只需要颜色,就能够只依赖于负责颜色的接口和模块,而不需要引入对字体的依赖(字体对客户透明)。

DIP: Dependency Inversion Principle

定义:High-level modules should be independent of low-level module implementation details. The most flexible systems are those in which source code dependencies refer only to abstraction, not to concretions.

就是说上层不要依赖下层,业务核心不要依赖具体实现。比如上文说的你的业务模型的实现不应该依赖于具体的数据库,而是应该把它抽象出去。

你可能感兴趣的:(读书笔记,架构,设计模式,经验分享,面试,程序人生)