Skip to content

Commit

Permalink
multiple general translation updates
Browse files Browse the repository at this point in the history
  • Loading branch information
yingang committed Feb 28, 2024
1 parent 6203371 commit a97b869
Show file tree
Hide file tree
Showing 12 changed files with 61 additions and 62 deletions.
20 changes: 5 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@

在线阅读:https://yingang.github.io/aposd-zh/

## 简介

<div style="inline">
<img src="./docs/cover.jpeg" width="210px" height="280px" />
</div>


## 简介

斯坦福教授、Tcl 语言发明者 John Ousterhout 的著作《A Philosophy of Software Design》,自出版以来,好评如潮。按照 IT 图书出版的惯例,如果冠名为“实践”,书中内容关注的是某项技术的细节和技巧;冠名为“艺术”,内容可能是记录一件优秀作品的设计过程和经验;而冠名为“哲学”,则是一些通用的原则和方法论,这些原则方法论串起来,能够形成一个体系。正如“知行合一”、“世界是由原子构成的”、“我思故我在”,这些耳熟能详的句子能够一定程度上代表背后的人物和思想。用一句话概括《A Philosophy of Software Design》,软件设计的核心在于降低复杂性。


Expand All @@ -20,7 +19,7 @@
- [第 2 章 复杂性的本质](docs/ch02.md)
- [第 3 章 能工作的代码是不够的](docs/ch03.md)
- [第 4 章 模块应该是深的](docs/ch04.md)
- [第 5 章 信息隐藏(和泄漏)](docs/ch05.md)
- [第 5 章 信息隐藏和信息泄露](docs/ch05.md)
- [第 6 章 通用模块更深入](docs/ch06.md)
- [第 7 章 不同的层,不同的抽象](docs/ch07.md)
- [第 8 章 降低复杂性](docs/ch08.md)
Expand Down Expand Up @@ -50,22 +49,13 @@
[yarn]: https://yarnpkg.com/
[vuepress]: https://v2.vuepress.vuejs.org/zh/


```sh
git clone https://github.com/yingang/aposd.git
cd A-Philosophy-of-Software-Design-zh/
git clone https://github.com/yingang/aposd-zh.git
cd aposd-zh/
yarn install # 安装 VuePress@next
yarn dev # 编译并打开网页预览
```

## 项目缘由

无意中看到这本书的相关介绍,也很快找到了 GitHub 上的民间翻译版,因为看到一些翻译不太恰当的地方,所以想着顺手提交修正下,然后找到其中 Star 数量比较多的主要是 [Cactus-proj](https://github.com/Cactus-proj/A-Philosophy-of-Software-Design-zh)[Go7hic](https://github.com/Go7hic/A-Philosophy-of-Software-Design) 的,但两者的内容几乎完全一样,包括翻译有错误的地方也错得一样。从实质内容的提交历史来看,应该 Cactus-proj 是更早的提交者,这一点从各自的 Fock/Star 数量也能侧面印证。

这两个项目均有收到并处理一些内容修正的 PR,但即使是 Cactus-proj,最新的几个 PR 也处于长期未处理的状态,应该都已经暂停维护了,然后基于 Cactus-proj,包含内容修复最多的是 [luojiego](https://github.com/luojiego/A-Philosophy-of-Software-Design-zh) 的 Fock,于是就基于这个创建了自己的 Fork。除了一边阅读一边校对,也摸索着更新了相关的部署脚本,同样部署到 GitHub Pages 上。

从提交历史来看,[gdut-yy](https://github.com/gdut-yy) 应该是主要的翻译贡献者,[liquid207](https://github.com/liquid207)[wanghuanwei](https://github.com/wanghuanwei)[luojiego](https://github.com/luojiego)[BlackGlory](https://github.com/BlackGlory) 也都贡献了比较多的翻译修正,[inkydragon](https://github.com/inkydragon) 则主要负责了 LaTeX 和 PDF 相关的工作,不确定历史是否挖掘充分,所有提到未提到的贡献者,一并感谢!

## License

[MIT](./LICENSE)
11 changes: 10 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
- [第 2 章 复杂性的本质](ch02.md)
- [第 3 章 能工作的代码是不够的](ch03.md)
- [第 4 章 模块应该是深的](ch04.md)
- [第 5 章 信息隐藏(和泄漏)](ch05.md)
- [第 5 章 信息隐藏和信息泄露](ch05.md)
- [第 6 章 通用模块更深入](ch06.md)
- [第 7 章 不同的层,不同的抽象](ch07.md)
- [第 8 章 降低复杂性](ch08.md)
Expand All @@ -29,3 +29,12 @@
- [第 20 章 设计性能](ch20.md)
- [第 21 章 结论](ch21.md)
- [总结](summary.md)

## 翻译说明

无意中看到这本书的相关介绍,也很快找到了 GitHub 上的民间翻译版,因为看到一些翻译不太恰当的地方,所以想着顺手提交修正下,然后找到其中 Star 数量比较多的主要是 [Cactus-proj](https://github.com/Cactus-proj/A-Philosophy-of-Software-Design-zh)[Go7hic](https://github.com/Go7hic/A-Philosophy-of-Software-Design) 的,但两者的内容几乎完全一样,包括翻译有错误的地方也错得一样。从实质内容的提交历史来看,应该 Cactus-proj 是更早的提交者,这一点从各自的 Fock/Star 数量也能侧面印证。

这两个项目均有收到并处理一些内容修正的 PR,但即使是 Cactus-proj,最新的几个 PR 也处于长期未处理的状态,应该都已经暂停维护了,然后基于 Cactus-proj,包含内容修复最多的是 [luojiego](https://github.com/luojiego/A-Philosophy-of-Software-Design-zh) 的 Fock,于是就基于这个创建了自己的 [Fork](https://github.com/yingang/aposd-zh)。除了一边阅读一边校对,也摸索着更新了相关的部署脚本,同样部署到 [GitHub Pages](https://yingang.github.io/aposd-zh/) 上,可直接在线阅读。

从提交历史来看,[gdut-yy](https://github.com/gdut-yy) 应该是主要的翻译贡献者,[liquid207](https://github.com/liquid207)[wanghuanwei](https://github.com/wanghuanwei)[luojiego](https://github.com/luojiego)[BlackGlory](https://github.com/BlackGlory) 也都贡献了比较多的翻译修正,[inkydragon](https://github.com/inkydragon) 则主要负责了 LaTeX 和 PDF 相关的工作,不确定历史是否挖掘充分,所有提到未提到的贡献者,一并感谢!

2 changes: 1 addition & 1 deletion docs/ch01.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@

> One of the best ways to improve your design skills is to learn to recognize red flags: signs that a piece of code is probably more complicated than it needs to be. Over the course of this book I will point out red flags that suggest problems related to each major design issue; the most important ones are summarized at the back of the book. You can then use these when you are coding: when you see a red flag, stop and look for an alternate design that eliminates the problem. When you first try this approach, you may have to try several design alternatives before you find one that eliminates the red flag. Don’t give up easily: the more alternatives you try before fixing the problem, the more you will learn. Over time, you will find that your code has fewer and fewer red flags, and your designs are cleaner and cleaner. Your experience will also show you other red flags that you can use to identify design problems (I’d be happy to hear about these).
改善设计技能的最好方法之一就是学会识别危险信号:信号表明一段代码可能比需要的复杂。在本书的过程中,我将指出一些危险信号,这些危险信号指示与每个主要设计问题有关的问题;最重要的内容总结在书的后面。然后,您可以在编码时使用它们:当看到红色标记时,停下来寻找可消除问题的替代设计。当您第一次尝试这种方法时,您可能必须尝试几种设计替代方案,然后才能找到消除危险信号的方案。不要轻易放弃:解决问题之前尝试的替代方法越多,您就会学到更多。随着时间的流逝,您会发现代码中的危险信号越来越少,并且您的设计越来越清晰。
改善设计技能的最好方法之一就是学会识别危险信号:危险信号表明一段代码可能比需要的复杂。在本书的过程中,我将指出一些危险信号,这些危险信号与一些主要的设计问题相关,其中最重要的内容总结在本书的最后。您可以在编码时使用它们:当看到危险信号时,停下来寻找可消除问题的替代设计。当您第一次尝试这种方法时,您可能必须尝试几种设计替代方案,然后才能找到消除危险信号的方案。不要轻易放弃:解决问题之前尝试的替代方法越多,您就会学到更多。随着时间的流逝,您会发现代码中的危险信号越来越少,并且您的设计越来越清晰。您自己的经验可能也涉及到其它一些可用于识别设计问题的危险信号(我很乐意听到这些)

> When applying the ideas from this book, it’s important to use moderation and discretion. Every rule has its exceptions, and every principle has its limits. If you take any design idea to its extreme, you will probably end up in a bad place. Beautiful designs reflect a balance between competing ideas and approaches. Several chapters have sections titled “Taking it too far,” which describe how to recognize when you are overdoing a good thing.
Expand Down
4 changes: 2 additions & 2 deletions docs/ch02.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@

> **Cognitive load**: The second symptom of complexity is cognitive load, which refers to how much a developer needs to know in order to complete a task. A higher cognitive load means that developers have to spend more time learning the required information, and there is a greater risk of bugs because they have missed something important. For example, suppose a function in C allocates memory, returns a pointer to that memory, and assumes that the caller will free the memory. This adds to the cognitive load of developers using the function; if a developer fails to free the memory, there will be a memory leak. If the system can be restructured so that the caller doesn’t need to worry about freeing the memory (the same module that allocates the memory also takes responsibility for freeing it), it will reduce the cognitive load. Cognitive load arises in many ways, such as APIs with many methods, global variables, inconsistencies, and dependencies between modules.
**认知负荷**:复杂性的第二个症状是认知负荷,这是指开发人员需要多少知识才能完成一项任务。较高的认知负担意味着开发人员必须花更多的时间来学习所需的信息,并且由于错过了重要的东西而导致错误的风险也更大。例如,假设 C 语言中的一个函数分配了内存,返回了指向该内存的指针,并假定调用者将释放该内存。这增加了使用该功能的开发人员的认知负担。如果开发人员无法释放内存,则会发生内存泄漏。如果可以对系统进行重组,以使调用者不必担心释放内存(分配内存的同一模块也负责释放内存),它将减少认知负担。(认知负荷出现在很多方面,例如有很多方法的API、全局变量、不一致和模块间的依赖)
**认知负荷**:复杂性的第二个症状是认知负荷,这是指开发人员需要多少知识才能完成一项任务。较高的认知负荷意味着开发人员必须花更多的时间来学习所需的信息,并且由于错过了重要的东西而导致错误的风险也更大。例如,假设 C 语言中的一个函数分配了内存,返回了指向该内存的指针,并假定调用者将释放该内存。这增加了使用该功能的开发人员的认知负荷。如果开发人员无法释放内存,则会发生内存泄漏。如果可以对系统进行重组,以使调用者不必担心释放内存(分配内存的同一模块也负责释放内存),它将减少认知负荷。(认知负荷出现在很多方面,例如有很多方法的API、全局变量、不一致和模块间的依赖)

> System designers sometimes assume that complexity can be measured by lines of code. They assume that if one implementation is shorter than another, then it must be simpler; if it only takes a few lines of code to make a change, then the change must be easy. However, this view ignores the costs associated with cognitive load. I have seen frameworks that allowed applications to be written with only a few lines of code, but it was extremely difficult to figure out what those lines were. **Sometimes an approach that requires more lines of code is actually simpler, because it reduces cognitive load.**
系统设计人员有时会假设可以通过代码行来衡量复杂性。他们认为,如果一个实现比另一个实现短,那么它必须更简单;如果只需要几行代码就可以进行更改,那么更改必须很容易。但是,这种观点忽略了与认知负荷相关的成本。我已经看到了只需要几行代码就能编写应用程序的框架,但是要弄清楚这些行是什么极其困难。**有时,需要更多代码行的方法实际上更简单,因为它减少了认知负担**
系统设计人员有时会假设可以通过代码行来衡量复杂性。他们认为,如果一个实现比另一个实现短,那么它必须更简单;如果只需要几行代码就可以进行更改,那么更改必须很容易。但是,这种观点忽略了与认知负荷相关的成本。我已经看到了只需要几行代码就能编写应用程序的框架,但是要弄清楚这些行是什么极其困难。**有时,需要更多代码行的方法实际上更简单,因为它减少了认知负荷**

![](./figures/00010.jpeg)

Expand Down
8 changes: 4 additions & 4 deletions docs/ch04.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
模块的接口包含两种信息:形式化信息和非形式化信息。接口的形式化部分在代码中明确指定,并且其中一些可以通过编程语言检查其正确性。例如,方法的形式化接口是其签名,其中包括参数的名称和类型、返回值的类型以及有关该方法引发的异常的信息。大多数编程语言都确保对方法的每次调用都提供了正确数量和类型的参数以匹配其签名。类的形式化接口包括其所有公有方法的签名以及任何公有变量的名称和类型。

> Each interface also includes informal elements. These are not specified in a way that can be understood or enforced by the programming language. The informal parts of an interface include its high-level behavior, such as the fact that a function deletes the file named by one of its arguments. If there are constraints on the usage of a class (perhaps one method must be called before another), these are also part of the class’s interface. In general, if a developer needs to know a particular piece of information in order to use a module, then that information is part of the module’s interface. The informal aspects of an interface can only be described using comments, and the programming language cannot ensure that the description is complete or accurate [^1]. For most interfaces the informal aspects are larger and more complex than the formal aspects.
> Each interface also includes informal elements. These are not specified in a way that can be understood or enforced by the programming language. The informal parts of an interface include its high-level behavior, such as the fact that a function deletes the file named by one of its arguments. If there are constraints on the usage of a class (perhaps one method must be called before another), these are also part of the class’s interface. In general, if a developer needs to know a particular piece of information in order to use a module, then that information is part of the module’s interface. The informal aspects of an interface can only be described using comments, and the programming language cannot ensure that the description is complete or accurate <sup>1</sup>. For most interfaces the informal aspects are larger and more complex than the formal aspects.
每个接口还包括了非形式化的元素。这些元素无法以编程语言可以理解或执行的方式进行指定。接口的非正形式化部分包括其高层级的行为,例如函数可能被设计为会删除由其参数之一所命名的文件。如果对类的使用存在限制(也许必须先调用一个方法才能调用另一个),则这些约束也是类接口的一部分。通常,如果开发人员需要了解特定信息才能使用模块,则该信息是模块接口的一部分。接口的非形式化方面只能使用注释来描述,而编程语言并不能确保描述是完整或准确的 [^1]。对于大多数接口,非形式化的部分要比形式化的部分更大和更复杂。
每个接口还包括了非形式化的元素。这些元素无法以编程语言可以理解或执行的方式进行指定。接口的非正形式化部分包括其高层级的行为,例如函数可能被设计为会删除由其参数之一所命名的文件。如果对类的使用存在限制(也许必须先调用一个方法才能调用另一个),则这些约束也是类接口的一部分。通常,如果开发人员需要了解特定信息才能使用模块,则该信息是模块接口的一部分。接口的非形式化方面只能使用注释来描述,而编程语言并不能确保描述是完整或准确的 <sup>1</sup>。对于大多数接口,非形式化的部分要比形式化的部分更大和更复杂。

> One of the benefits of a clearly specified interface is that it indicates exactly what developers need to know in order to use the associated module. This helps to eliminate the “unknown unknowns” problem described in Section 2.2.
Expand Down Expand Up @@ -154,7 +154,7 @@ private void addNullValueForAttribute(String attribute) {

> ![](./figures/00013.jpeg) Red Flag: Shallow Module ![](./figures/00013.jpeg)
![](./figures/00013.jpeg) 危险信号:浅模块 ![](./figures/00013.jpeg)
![](./figures/00013.jpeg) 危险信号:浅模块 ![](./figures/00013.jpeg)

> A shallow module is one whose interface is complicated relative to the functionality it provides. Shallow modules don’t help much in the battle against complexity, because the benefit they provide (not having to learn about how they work internally) is negated by the cost of learning and using their interfaces. Small modules tend to be shallow.
Expand Down Expand Up @@ -204,4 +204,4 @@ FileInputStream 对象仅提供基本的 I/O:它不能执行缓冲的 I/O,

> <sup>1</sup> There exist languages, mostly in the research community, where the overall behavior of a method or function can be described formally using a specification language. The specification can be checked automatically to ensure that it matches the implementation. An interesting question is whether such a formal specification could replace the informal parts of an interface. My current opinion is that an interface described in English is likely to be more intuitive and understandable for developers than one written in a formal specification language.
[^1] 当前存在一些编程语言(主要是在研究社区中),可以在其中使用某种规范语言来对方法或功能的整体行为进行形式化的描述,也可以自动地检查该规范以确保它与实现相匹配。一个有趣的问题是,这样的形式化规范是否可以代替接口的非形式化部分。我目前的观点是,用英语描述的接口比使用形式化的规范语言编写的接口对开发人员来说更直观和易于理解。
<sup>1</sup> 当前存在一些编程语言(主要是在研究社区中),可以在其中使用某种规范语言来对方法或功能的整体行为进行形式化的描述,也可以自动地检查该规范以确保它与实现相匹配。一个有趣的问题是,这样的形式化规范是否可以代替接口的非形式化部分。我目前的观点是,用英语描述的接口比使用形式化的规范语言编写的接口对开发人员来说更直观和易于理解。
Loading

0 comments on commit a97b869

Please sign in to comment.