关于软件设计哲学的注意事项。
建筑(30), review (13), 书(14)Jumping on the recent trend, I picked up a copy ofA Philosophy of Software Design基于John SuilthoutCindy’s recommendation。在160页很简洁,I skimmed through it over the last few days, writing up some notes along the way.
Michael Krause也很友好,以指出John Outshout的伟大的谈话涵盖相同的内容。
A Philosophy看看软件的复杂性,并希望您使用复杂性来指导软件设计通过其寿命。“作者在软件设计上运行了本科课程,在教学写作的方法之后建模(草稿,写作,批判,重写,批评,重写再次),并使用这种经验,结合了许多遗产的长期职业生涯制定复杂性和缓解的类别。
They particularly recommend the book as a useful tool to use during code reviews, providing a list of red flags along the lines of information leakage, shallow module, vague names, implementation documentation contaminates interfaces, conjoined methods, and general-specific mixture. (A full list of red-flags at bottom.)
Now, a list of snippets I found particularly interesting.
Complexity is anything that makes software hard to understand or to modify.
虽然这本书的进展,但虽然它变得更加专注于复杂性的广泛定义。
在很少相互作用的地方隔离复杂性大致相当于消除复杂性。
这是,我想,相当明显,但令我欣赏我的洞察力。我们没有足够的思考我们在哪里产生复杂性,如果我们做得更好,我们可以快速使我们的系统更简单。
复杂性对读者来说比作家更加明显。如果其他人认为一段代码很复杂,那就是。
An old refrain, but a good one. It’s surprising how resistant folks can be to this feedback, including myself.
The book picks three symptoms of complexity: change amplification, cognitive load, unknown unknowns. Change amplification is when making a local change requires many changes elsewhere, and is best prevented when you
减少受每个设计决策影响的代码量,因此设计更改不需要非常多的代码修改。
认知负荷要求我们将我们的心态转移到计数代码线,而是接受更多,更简单,代码行仍然比更少的复杂线更简单。(这是我开始写作更多的时候挣扎的东西。一切都很简单,但它比我习惯于在Python写作的时间长。)
最后,未知的未知是您想知道的事情,但没有合理的方式让您从代码本身学习。
It then moves on to a definition of complexity:
Complexity is caused by obscurity and dependencies.
And definitions of complexity’s subcomponents:
Dependency is when code can't be understood in isolation. Obscurity is when important information is not obvious. This can often be due to lack of documentation.
Why is complexity so challenging to manage? It’s because
Complexity is incremental, the result of thousands of choices. Which makes it hard to prevent and even harder to fix.
打击复杂性蔓延,他建议区分strategic programming和tactical programming。
Tactical mindset is focused on getting something working, but makes it nearly impossible to produce good system design.
相反,战略编程转移了目标帖子。
战略编程正在意识到工作代码是不够的。主要目标是一个很好的设计,也解决了您的问题,而不是工作代码。
Interestingly, the proposal is not that you should do major upfront design phases, but instead that you should be doing lots of incremental design improvement work over time. This is slightly different than just “doing Agile”, because Agile is too focused with features, whereas
The increments of development should be abstractions, not features. ... Ideally, when you have finished with each change, the system will have the structure it would have had if you had designed it from the start with that change in mind.
Many folks would argue against this focus on abstractions, arguing that it’s not obviously useful, in terms of the你不会需要它,但他争辩说
良好设计的回报迅速。对于第一个版本来说,战术方法不太可能是更快的,更不用说第二个。
That section is specifically a refutation of the startup mentality of launching quickly and fixing things later as a false dichotomy.
The most important way to manage complexity is by shifting it from interfaces and into implementation:
模块是接口和实现。最好的模块是界面比实现更简单的位置。...对于模块具有比简单实现更简单的界面更重要。
You have to be careful when designing modules thought, because
抽象是省略不重要细节的实体的简化视图。省略重要的细节导致默默无闻,创造了一个错误的抽象。
Done well this technique is known as information hding:
Each module should encapsulate a few pieces of knowledge, which represent design decisions. This knowledge should not appear in its interfaces, and hence are restricted to its implementation. Simpler interfaces correlate with better information hiding.
The opposite of information hiding is information leakage:
When a design decision is used across multiple modules, coupling them together.
这本书花了一段时间讨论异常以及它们如何与正常的代码流程的偏差导致它们引起比其代码行可能建议的更多问题。这是因为你
必须尝试恢复(硬)或试图修复和向前移动(也很难)来恢复。这导致许多情况下不一致。
The solution is to “define errors out of existance,” which is designing interfaces such that errors are not possible. The example ofunset
相对删除
被给出,前者会确保某些东西不存在,而不是确保以前存在的东西已经消失了。这项技术的第二个例子是从列表中拍摄切片,它更容易返回不存在的范围,而不是抛出有关超出界限的错误。
最好的设计不是你的第一个设计,而是你应该
Design it twice, taking radically different approaches.
There is an interesting aside on this topic, mentioning how very smart people often have been drilled by their early experiences that their first inclination is the right one because it’s good enough to get a good grade, and consequently they struggle to take advantage of this technique.
Most large software design problems are fundamentally different than school work in that they are not inherently designed to be solvable, and consequently they benefit from multiple different approaches.
Finally, a closing benediction to the strategic mindset:
If you're not making the design better, you are probably making it worse.
Altogether, this was a really good read, and I highly recommend it!
Red flags
这里提出了这本书的全部红旗列表,虽然您必须购买该书以获得定义!
- Shallow module
- Information leakage
- Temporal decomposition
- Overexposure
- 通过方法
- Repetition of the same fragments of code
- General-specific mixture
- Conjoined methods
- 非明显的代码
- Hard to describe
- 评论重复代码
- Vague names
- 难以挑选名字
- Implementation documentation contaminates interfaces