新書推薦:
《
罗马之变(法语直译,再现罗马共和国走向罗马帝国的辉煌历史)
》
售價:NT$
500.0
《
自然之争:1600年以来苏格兰和英格兰北部地区的环境史(新史学译丛)
》
售價:NT$
485.0
《
硝烟下的博弈:工业革命与中西方战争
》
售價:NT$
398.0
《
让内的理性主义 发现无意识之旅
》
售價:NT$
301.0
《
知命不惧:从芝诺到马可·奥勒留的生活艺术
》
售價:NT$
505.0
《
Zemax光学设计从基础到实践
》
售價:NT$
602.0
《
全球化的黎明:亚洲大航海时代
》
售價:NT$
500.0
《
危局
》
售價:NT$
383.0
編輯推薦:
善用软件架构的通用法则,即可显著提升开发者在所有软件系统全生命周期内的生产力。如今,传奇软件匠师Robert C. Martin(Bob大叔),携畅销书Clean Code与The Clean Coder所获巨大成功之威,向我们深刻揭示了这些法则并亲授运用之道。
Martin在《架构整洁之道》中远不只是在为我们提供选项,他几乎是在将软件世界中横跨半个世纪的各种架构类型的经验倾囊相授,目的是让读者既能阅尽所有架构选型,又可通晓其如何决定成败。Martin也的确不负厚望,本书中充满了直接而有效的解决方案,以供读者应对自己面临的真正挑战那些或最终成就或彻底破坏项目的挑战。
《架构整洁之道》不可不读,无论读者是现任的还是将来的软件架构师、系统分析师、系统设计师或软件项目经理,或是身负将他人设计落地重任的开发人员,这本书都可以让你们受益匪浅。
內容簡介:
《架构整洁之道》是创造“Clean神话”的Bob大叔在架构领域的登峰之作,围绕“架构整洁”这一重要导向,系统地剖析其缘起、内涵及应用场景,涵盖软件研发完整过程及所有核心架构模式。本书分为6部分,第1部分纲领性地提出软件架构设计的终极目标,描述软件架构设计的重点与模式;第2~4部分从软件开发中三个基础编程范式的定义和特征出发,进一步描述函数、组件、服务设计与实现的定律,以及它们是如何有效构建软件系统的整体架构的;第5部分从整洁架构的定义开始,详细阐述软件架构设计过程中涉及的方方面面,包括划分内部组件边界、应用常见设计模式、避开错误、降低成本、处理特殊情况等,并以实战案例将内容有机整合起来;第6部分讲述具体实现细节;附录则透过作者数十年的软件从业经历再次印证本书的观点。对于每一位软件研发从业人员——无论从事的是具体编码实现、架构设计,还是软件研发管理,本书都是不可或缺的。
關於作者:
Robert C. Martin,Object Mentor公司总裁,面向对象设计、模式、UML、敏捷方法学和极限编程领域的资深顾问。他是Designing Object-Oriented C++ Applications Using the Booch Method 以及 Jolt 获奖图书 Agile Software Development, Principles,Palterns,and Practices中译版《敏捷软件开发:原则、模式与实践》《代码整洁之道》等畅销书作者。
孙宇聪:曾在谷歌工作多年,任谷歌高级SRE(Senior Site Reliblity Engineer),前Coding.net 技术负责人。
目錄 :
第1部分概述
第1章设计与架构究竟是什么3
目标是什么4
案例分析5
本章小结11
第2章两个价值维度12
行为价值13
架构价值13
哪个价值维度更重要14
艾森豪威尔矩阵15
为好的软件架构而持续斗争16
第2部分从基础构件开始:编程范式
第3章编程范式总览21
结构化编程22
面向对象编程22
函数式编程23
仅供思考23
本章小结24
第4章结构化编程25
可推导性26
goto是有害的28
功能性降解拆分29
形式化证明没有发生29
科学来救场29
测试30
本章小结31
第5章面向对象编程32
封装33
继承36
多态38
本章小结44
第6章函数式编程45
整数平方46
不可变性与软件架构47
可变性的隔离48
事件溯源49
本章小结51
第3部分设计原则
第7章SRP:单一职责原则56
反面案例2:代码合并59
解决方案60
本章小结61
第8章OCP:开闭原则62
思想实验63
依赖方向的控制67
信息隐藏67
本章小结67
第9章LSP:里氏替换原则68
继承的使用指导69
正方形长方形问题70
LSP与软件架构70
违反LSP的案例71
本章小结73
第10章 ISP:接口隔离原则74
ISP与编程语言76
ISP与软件架构76
本章小结77
第11章 DIP:依赖反转原则78
稳定的抽象层79
工厂模式80
具体实现组件82
本章小结82
第4部分组件构建原则
第12章 组件84
组件发展史85
重定位技术88
链接器88
本章小结90
第13章 组件聚合91
复用发布等同原则92
共同闭包原则93
共同复用原则94
组件聚合张力图95
本章小结97
第14章 组件耦合98
无依赖环原则99
自上而下的设计105
稳定依赖原则106
稳定抽象原则112
本章小结117
第5部分软件架构
第15章 什么是软件架构120
开发(Development)122
部署(Deployment)123
运行(Operation)123
维护(Maintenance)124
保持可选项124
设备无关性126
垃圾邮件128
物理地址寻址129
本章小结130
第16章 独立性131
用例132
运行133
开发133
部署134
保留可选项134
按层解耦135
用例的解耦136
解耦的模式136
开发的独立性137
部署的独立性137
重复138
再谈解耦模式139
本章小结141
第17章 划分边界142
几个悲伤的故事143
FitNesse146
应在何时、何处画这些线148
输入和输出怎么办151
插件式架构152
插件式架构的好处153
本章小结154
第18章 边界剖析155
跨边界调用156
令人生畏的单体结构156
部署层次的组件158
线程159
本地进程159
服务160
本章小结161
第19章 策略与层次162
层次(Level)163
本章小结166
第20章 业务逻辑167
业务实体168
用例169
请求和响应模型171
本章小结172
第21章 尖叫的软件架构173
架构设计的主题174
架构设计的核心目标175
那Web呢175
框架是工具而不是生活信条175
可测试的架构设计176
本章小结176
第22章 整洁架构177
依赖关系规则179
一个常见的应用场景183
本章小结184
第23章 展示器和谦卑对象185
谦卑对象模式186
展示器与视图186
测试与架构187
数据库网关188
数据映射器188
服务监听器189
本章小结189
第24章 不完全边界190
省掉最后一步191
单向边界192
门户模式193
本章小结193
第25章 层次与边界194
基于文本的冒险游戏:Hunt The Wumpus195
可否采用整洁架构196
交汇数据流199
数据流的分割199
本章小结201
第26章 Main组件203
最细节化的部分204
本章小结208
第27章 服务:宏观与微观209
面向服务的架构210
服务所带来的好处210
运送猫咪的难题212
对象化是救星213
基于组件的服务215
横跨型变更216
本章小结216
第28章 测试边界217
测试也是一种系统组件218
可测试性设计219
测试专用API220
本章小结221
第29章 整洁的嵌入式架构222
程序适用测试测试225
目标硬件瓶颈228
本章小结238
第6部分实现细节
第30章 数据库只是实现细节240
关系型数据库241
为什么数据库系统如此流行242
假设磁盘不存在会怎样243
实现细节243
但性能怎么办呢244
一段轶事244
本章小结246
第31章 Web是实现细节247
无尽的钟摆248
总结一下250
本章小结251
第32章 应用程序框架是实现细节252
框架作者253
单向婚姻253
风险254
解决方案255
不得不接受的依赖255
本章小结256
第33章 案例分析:视频销售网站257
产品258
用例分析258
组件架构260
依赖关系管理261
本章小结262
第34章 拾遗263
按层封装264
按功能封装266
端口和适配器268
按组件封装270
具体实现细节中的陷阱274
组织形式与封装的区别275
其他的解耦合模式277
本章小结:本书拾遗279
后序280
附录A架构设计考古283
內容試閱 :
推荐序一
在我心里,程序员可以分为三个层次:普通程序员、工程师和架构师。
普通程序员是编写代码的人。编写代码的方式有很多,只要能让程序跑起来,能正确地处理业务流程和对数据进行计算,就可以说会编写代码。程序员需要熟悉整个程序的逻辑及处理过程,需要熟悉程序语言的特性,还需要熟悉一些计算机操作系统的交互调用方式,才能写出从用户侧交互,到数据和业务逻辑处理,再到与计算机系统交互的代码,有效地把用户信息、数据、业务和计算机串联和拼装出来。
然而,其中一些程序员发现,只让代码跑起来是不够的,因为这个世界是不断变化的,他们发现自己需要花更多的时间来维护代码:增加新的需求,扩展原有的流程,修改已有的功能,优化性能一个人完全维护不过来,还需要更多的人,于是代码还需要在不同人之间轮转;他们发现代码除了需要跑起来,还需要易读、易扩展、易维护,甚至可以直接重用。于是,这些人使用各种各样的手段和技术不断提高代码的易读性、可扩展性、可维护性和重用性。我们把这些有洁癖、有工匠精精、有修养的程序员叫作工程师,工程师不仅仅是在编写代码,他们会用工程的方法来编写代码,以便让编程开发更为高效和快速。他们把编程当成一种设计,一种工业设计,把代码模块化,让这些模块可以更容易地交互拼装和组织,让代码排列整齐阅读和维护这些代码就像看阅兵式一样舒心畅快。
但是故事还没完,这些拥有工匠精神的工程师们还是难以解决某些问题,这些人渐渐地发现,这个世界上有很多问题就像翘翘板一样,只能要一边,这一边上去了,另一边就下来了。就像要么用空间换时间,要么用时间换空间一样,你很难找到同时满足空间和时间要求的双利解;就像CAP的三选二的理论一样,这个世界不存在完美的解决方案,无论什么方案都有好的一面和不好的一面。而且,这些工程师还渐渐发现,每当引入一个新的技术来解决一个已有的问题时,这个新的技术就会带来更多的问题,问题就像有一个生命体一样,它们会不断地繁殖和进化。渐渐地,他们发现,问题的多少和系统的复杂度呈正比,而且不仅是线性正比,还可能呈级数正比,此时就越来越难做技术决定。但是有一些资深的工程师开始站出来挑战这些问题,有的基于业务分析给出平衡的方案,有的开始尝试设计更高级的技术,有的开始设计更灵活的系统,有的则开始简化和轻量化整个系统这些高智商、经验足、不怕难的工程师们引领着整个行业前行。他们就是架构师!
感觉Bob大叔的系列著作好像也在走这个过程,《代码整洁之道》教你写出易读、可扩展、可维护、可重用的代码,《代码整洁之道:程序员的职业素养》教你怎样变成一个有修养的程序员,而《架构整洁之道》基本上是在描述软件设计的一些理论知识。《架构整洁之道》大体分成三个部分:编程范式(结构化编程、面向对象编程和函数式编程),设计原则(主要是SOLID),以及软件架构(其中讲了很多高屋建翎的内容)。总体来说,这本书中的内容可以让你从微观(代码层面)和宏观(架构层面)两个层面对整个软件设计有一个全面的了解。
但是,如果你想从这本书里找到一些可以立马解决具体问题的工程架构和技术,恐怕你会感到失望。这本书中更多的是一些基础的理论知识,看完后你可能会比较无感,因为这些基础知识对于生活在这个高速发展的喜欢快餐文化的社会中的人来说,可能很难理解其中的价值大多数人的目标不是设计出一个优质的软件或架构,而是快速地解决一个具体的问题,完成自己的工作。然而,可能只有你碰过足够多的壁,掉过足够多的坑,经历过足够多的痛苦后,再来读这本书时,你才会发现本书中的这些陈旧的知识是多么充满智慧。而且,如果有一天,你像我这个老家伙一样,看到今天很多很多公司和年轻的程序员还在不断地掉坑和挣扎,你就会明白这些知识的重要性了。
我个人觉得,这本书是架构方面的入门级读物,但也并不适合经验不足的人员学习,这本书更适合的读者群是,有3~5年编程经验、需要入门软件设计和架构的工程师或程序员。
最后,我想留下一个观点和一组问题。
观点:无论是微观世界的代码,还是宏观层面的架构,无论是三种编程范式还是微服务架构,它们都在解决一个问题分离控制和逻辑。所谓控制就是对程序流转的与业务逻辑无关的代码或系统的控制(如多线程、异步、服务发现、部署、弹性伸缩等),所谓逻辑则是实实在在的业务逻辑,是解决用户问题的逻辑。控制和逻辑构成了整体的软件复杂度,有效地分离控制和逻辑会让你的系统得到最大的简化。
问题:如果你要成为一名架构师,你需要明确地区分几组词语(如何区分它们正是留给你的问题),否则你不可能成为一名合格的工程师或架构师。这几组词语是简单vs.简陋、平衡vs.妥协、迭代vs.半成品。如果你不能很清楚地定义出其中的区别,那么你将很难做出正确的决定,也就不可有成为一名优秀的工程师或架构师。
我相信这个观点和这组问题将有助于你更好地阅读并理解这本书,也会让你进行更多的思考,带着思考读这本书,会让你学到更多!
陈皓
(@左耳朵耗子)
推荐序二
久远的教诲,古老的智慧
如果让你接手一套不稳定但要紧的在线系统,这套系统还有各种问题:变量命名非常随意,依赖逻辑错综复杂,层次结构乱七八糟,部署流程一塌糊涂,监控系统一片空白你该怎么办?
前几年我就遇到了这种问题,我对着频发的故障仔细观察,发现了最关键的问题:如果放着不动,这套系统的核心功能还是相对稳定的,但经常会有一些外围需求要开发,这时由于原有的依赖逻辑和层次结构不够清楚,就会导致牵一发而动全身的情况,加上测试不完善,所以几乎每次外围功能上线更新,核心功能都会受影响,然后又要重复好几次调试改正上线的流程。
怎么办?大家说了很多办法:把单元测试都补全,重构代码拆分核心功能和非核心功能,跟业务方谈暂停需求这些办法都很对,但是,都需要时间才能见效,而我们最缺的就是时间。
我提了一个很笨的办法:把所有共享变量都抽到Redis中进行读写,消灭本地副本,然后把稳定版本程序多部署几份,这样就可以多启动几个实例,将这些实例标记为AB两组。同时,在前面搭建代理服务,用于分流请求核心功能请求分配到A组(程序基本不更新),外围功能请求分配到B组(程序按业务需求更新)。这样做看起来有点多此一举AB两组都只有部分代码提供服务,而且要通过Redis共享状态,但是却实现了无论B组的程序如何更新,都不会影响A组所承载的核心服务的目的。
虽然当时不少人说怎么能这样玩呢,但它确实有效。当天部署,当天生效,在线服务迅速稳定下来,即便新开发的外围功能有问题,核心服务也不受任何影响。这样业务人员满意了,开发人员也可以安心对系统做改造了。
后来有不少人问我是怎么想到这个办法的,答案是:因为我是个老程序员,成长在面向对象的年代,运用SOC(关注点分离)、SRP(单一职责原则)、OCP(开闭原则)这些东西对我来说就如同本能。具体到这个例子,无非就是识别关注点、隔离责任、保持核心关注点的封闭而已。
后来我才知道,我提出的这个方法有个专门的名字叫蓝绿部署。当然我自认是个老程序员,不懂这些新鲜概念也不太要紧。确实,如今不少程序员已经不认识SOC、SRP、OCP、LSP等古老的玩意了,大家熟悉的是各种语言、类库、框架、代码托管网站。互联网开发场景千变万化,技术一日千里,而面向对象在不少人的脑海里早就是弃之不用的老古董了。只有老一辈的程序员还记得那些古老的教诲,守着那些古拙的技巧。但是这些东西,总有一天会被时代淘汰吗?
实际上,这也是我初读《架构整洁之道》的疑惑。虽然Bob大叔这个名字对我们这些老程序员来说可谓如雷贯耳,之前针对一般性软件开发所著的《代码整洁之道》和《代码整洁之道:程序员的职业素养》也确实很受欢迎,但如今写架构,还从结构化编程、面向对象编程、函数式编程写起,还花时间解释SRP、OCP、LSP等原则,实在难掩古老的感觉。请问,它们和如今的架构有什么关系吗?
不过,如果你耐心读下去就会发现,还真有关系。按照Bob大叔的说法,所谓架构就是用最小的人力成本来满足构建和维护系统需求的设计行为。以前的面向对象系统和如今的分布式系统,在这一点上是完全一致的。听取久远的教诲,尊重古老的智慧,如今的架构师也会从中受益。不信?我们就拿经典的三个编程范式来举例,看看这些老掉牙的玩意儿和如今的架构设计有什么关联。
大家对结构化编程的一般理解是,由if-else、switch-case之类的语句组织程序代码的编程方式,它杜绝了goto导致的混乱。但是从更深的层次上看,它也是一种设计范式,避免随意使用goto,使用if-else、switch-case之类控制语句和函数、子函数组织起来的程序代码,可以保证程序的结构是清楚的,自顶向下层层细化,消灭了杂错,杜绝了混淆。
联系如今的分布式系统,我们在设计的时候,真的能够做到自顶向下层层细化吗?有多少次,我看到的系统设计图里,根本没有层次的概念,各个模块没有一致的层次划分,与子系统交互的不是子系统,而是一盘散沙式的接口,甚至接口之间随意互调、关系乱成一团麻的情况也时常出现,带来的就是维护和调试的噩梦。吹散历史的迷雾,不正是古老的goto陷阱的再现吗?
大家对面向对象编程的一般理解是,由封装、继承、多态三种特性支持的,包含类、接口等若干概念的编程方式。但是从更深的层次上看,它也是一种设计范式。多态大概算其中最神奇的特性了,程序员在确定接口时做好抽象,代码就可以很灵活,遇到新情况时,新写一个实现就可以无缝对接。
联系如今的分布式系统,我们在设计的时候,真的能够做到接口足够抽象、新模块能无缝对接吗?有多少次,我看到接口的设计非常随意,接口不是基于行为而是基于特定场景的实现,没有做适当的抽象,也没有为未来预留空间,直接导致契约僵硬死板。每新增一种终端呈现形式,整个内容生产流程就要大动干戈,这样的例子并不罕见。抹去历史的