Programming Principles(编程准则)

本文已开源发布在这里“Programming Priciples-中文版”
如果觉得还不错,可以在GitHub给本文章标星☆鼓励

Every programmer benefits from understanding programming principles and patterns. This overview is a reference for myself, and I’ve just put it here. Maybe it is of help to you during design, discussion, or review. Please note that it’s far from complete, and that you often need to make trade-offs between conflicting principles.

每一位开发者都可以从编程准则和模式的学习上获益。这一篇概览性质的参考资料是为自己总结的,现在把它分享在这里。或许它可以在设计、探讨、评审的过程中给予你帮助。不过也请您知晓,它距离完整还差很多,所以在平时使用的过程中,你需要自己去分辨这些编程准则之间的冲突与不同,以便更好地应用于实践当中。

The list was inspired by The Principles of Good Programming. I felt that the list closely, but not completely matches what I would personally put into something similar. Additionally, I wanted a bit more reasoning, details, and links to further resources. Let me know if you have any feedback or suggestions for improvement.

这份列表的灵感来源于这篇文章The Principles of Good Programming。我感觉到这篇文章描述的内容与本篇非常地相似,但是和我想要阐述的却是相近而不相同。所以额外的,我希望在这些准则的阐述过程中,包含更多的关于应用原因、细节的描述以及深入解读的资料超链接。如果你有建议或者有问题需要反馈,可以提issues给我Let me know

Generic

通用

Inter-Module/Class

内部模块/类

Module/Class

模块/类

KISS

KISS准则

Most systems work best if they are kept simple rather than made complex.

如果能够保持系统简单复杂性低,那么大多数的系统都可以运行的很好。

Why

为什么?

Resources

更多资料

YAGNI

YAGNI准则

YAGNI stands for “you aren’t gonna need it”: don’t implement something until it is necessary.

YAGNI英文描述为 “you aren’t gonna need it”:直到使用之前都不要去实现它。

Why

为什么?

How

怎么办?

Resources

更多资料

Do The Simplest Thing That Could Possibly Work

做最简单最可能实现的事情

Why

为什么?

How 怎么办?

Resources

更多资料

Separation of Concerns

关注点分离

Separation of concerns is a design principle for separating a computer program into distinct sections, such that each section addresses a separate concern. For example the business logic of the application is a concern and the user interface is another concern. Changing the user interface should not require changes to business logic and vice versa.

关注点分离,是将计算机程序分成不同部分的设计原则,使每个部分都涉及到单独的问题。 例如,应用程序的业务逻辑是一个问题,用户界面是另一个问题。 更改用户界面不应要求对业务逻辑进行更改,反之亦然。

Quoting Edsger W. Dijkstra (1974):

引证 Edsger W. Dijkstra (1974):

It is what I sometimes have called “the separation of concerns”, which, even if not perfectly possible, is yet the only available technique for effective ordering of one’s thoughts, that I know of. This is what I mean by “focusing one’s attention upon some aspect”: it does not mean ignoring the other aspects, it is just doing justice to the fact that from this aspect’s point of view, the other is irrelevant. 通常意义上所谈到的“关注点分离”,或许不是完全可能,我所知道的是它依然更多地依赖于个人对于事情场景的观点和想法。其实我所更想提及的是“把一个人的焦点放在某一个方面”:这并不意味着要忽略其他的方面,只是更多地期望能在关注的方面或者说角度上,找到根本的原因和事实,而不是其它不相关的部分。

Why

为什么?

How

怎么办?

Resources

更多资料

Keep things DRY

DRY原则

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

在一个系统内,每一项知识点的表现必须是单一的,明确无歧义的,具备权威性的。

Each significant piece of functionality in a program should be implemented in just one place in the source code. Where similar functions are carried out by distinct pieces of code, it is generally beneficial to combine them into one by abstracting out the varying parts.

源代码中的每一项重要的程序功能只应该出现在一个地方。当我们遇到不同的代码段实现了相类似的功能,通常地,我们把不同的部分抽象出来,然后把相同的部分放在公共层,以实现更高的复用性。

Why

为什么?

How

怎么办?

Resources

更多资料

Related

引用

Code For The Maintainer

编写可维护的代码

Why

为什么?

How

怎么办?

Resources

更多资料

Avoid Premature Optimization

避免过度过早优化

Quoting Donald Knuth:

引用 唐纳德·克努斯:

Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. 程序员花费极大的时间去思考、担心哪些程序里非关键部位的运行速度,而这种种在调试、维护上的工作效能方面常常引发了负面的影响。我们应该摒弃那些花费了97%时间去做的低效能的事情。过早的优化是所有邪恶的根源。不管怎样,我们不能放弃那3%关键部分的机会。

Understanding what is and isn’t “premature” is critical of course.

对于是否属于“过早的优化”,这是一项关键的课程。

Why

为什么?

How

怎么办?

Resources

更多资料

Boy-Scout Rule

美国童子军准则

The Boy Scouts of America have a simple rule that we can apply to our profession: “Leave the campground cleaner than you found it”. The boy-scout rule states that we should always leave the code cleaner than we found it.

美国童子军有一项简单的准则:“离开野营区之时保证要比自己来的时候更加干净”。我们可以将这一准则应用在计算机方面:“时常迫使代码比我们发现它的时候更整洁更清晰”。

Why

为什么?

How

怎么办?

Resources

更多资料

Minimise Coupling

低耦合

Coupling between modules/components is their degree of mutual interdependence; lower coupling is better. In other words, coupling is the probability that code unit “B” will “break” after an unknown change to code unit “A”.

耦合度指的是模块/组件之间的相互依赖程度。耦合度越低则越好。换句话说,耦合度高会导致代码单元“B”因为代码单元“A”的一个未知变更而被打断。

Why

为什么?

How

怎么办?

Resources

更多资料

Law of Demeter

迪米特法则

Don’t talk to strangers.

不要告诉陌生人。

Why

为什么?

How

怎么办?

A method of an object may only call methods of:

一个对象的一个方法,只能调用如下内容:

  1. The object itself.
  2. 对象本身。
  3. An argument of the method.
  4. 方法参数。
  5. Any object created within the method.
  6. 方法内所创建的对象。
  7. Any direct properties/fields of the object.
  8. 对象内直接包含的属性、字段。

Resources

更多资料

Composition Over Inheritance

组合优于继承

Why

为什么?

How

怎么办?

Resources

更多资料

Orthogonality

正交性

The basic idea of orthogonality is that things that are not related conceptually should not be related in the system. 正交性的基本定义是,系统内概念不相同的部分,不应该形成关联和依赖。

Source: Be Orthogonal

引用: Be Orthogonal

It is associated with simplicity; the more orthogonal the design, the fewer exceptions. This makes it easier to learn, read and write programs in a programming language. The meaning of an orthogonal feature is independent of context; the key parameters are symmetry and consistency. 它与简单性有关,设计的时候正交性越高,则异常发生地越少。这通常会使得代码变得更加容易学习、阅读和编写,无论你使用的是哪一种编程语言。正交性的一个典型特征是上下文之间互相没有依赖,核心参数之间会保持对称性和一致性。

Source: Orthogonality

引用: Orthogonality

Robustness Principle

健壮性原则

Be conservative in what you do, be liberal in what you accept from others 对内保持保守,对外保持自由。

Collaborating services depend on each others interfaces. Often the interfaces need to evolve causing the other end to receive unspecified data. A naive implementation refuses to collaborate if the received data does not strictly follow the specification. A more sophisticated implementation will still work ignoring the data it does not recognize.

协作服务依赖于各式各样的接口。通常地,接口的演变会致使另外一端接收到未指定的数据。倘若数据结构没有遵循规范,那么一个简单的不健壮的实现会遭到拒绝。一个健壮的实现会主动忽略不可识别的数据,继而持续工作。

Why

为什么?

How

怎么办?

Resources

更多资料

Maximise Cohesion

高内聚

Cohesion of a single module/component is the degree to which its responsibilities form a meaningful unit; higher cohesion is better.

一个单一模块/组件的内聚性指的是它的职责形成了有具体含义的独立单元。内聚性自然越高也好。

Why

为什么?

How

怎么办?

Resources

更多资料

Liskov Substitution Principle

里氏替换原则

The LSP is all about expected behavior of objects:

里氏替换原则是关于对象预期行为方面的描述:

Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program. 程序内的对象理应可以被它的子类所无缝替换,此间不需要作任何的程序订正操作。

Resources

更多资料

Open/Closed Principle

开闭原则

Software entities (e.g. classes) should be open for extension, but closed for modification. I.e. such an entity can allow its behavior to be modified without altering its source code.

软件实体(例如类)理应对扩展开放,对修改关闭。例如一个实体可以允许它的动作不需要经过修改源码而发生的演变。

Why

为什么?

How

怎么办?

Resources

更多资料

Single Responsibility Principle

单一职责原则

A class should never have more than one reason to change.

一个类不应该包含多于一个职责。

Long version: Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class. Responsibility can be defined as a reason to change, so a class or module should have one, and only one, reason to change.

长文字版本:每一个类都应该有一个职责,而这个职责应该被这个类所内聚。职责被定义为发生改变的一个原因,即一个类或者模块有且仅有一个原因会致使其发生演变。

Why

为什么?

How

怎么办?

Resources

更多资料

Hide Implementation Details

隐藏实现细节

A software module hides information (i.e. implementation details) by providing an interface, and not leak any unnecessary information.

一个软件模块应该隐藏一些信息(例如实现细节),仅提供一个接口即可,以确保不泄露任何不必要的信息。

Why

为什么?

How

怎么办?

Resources

更多资料

Curly’s Law

科里定律

Curly’s Law is about choosing a single, clearly defined goal for any particular bit of code: Do One Thing.

科里定律是关于如何为任一特定代码段选择一项单一的、定义明确的目标的一项法则:只作一件事。

Encapsulate What Changes

封装性

A good design identifies the hotspots that are most likely to change and encapsulates them behind an API. When an anticipated change then occurs, the modifications are kept local.

一项好的设计意味着某些很有可能被修改和内聚的热点部分被隐藏在API的后方。当预期的变更出现时,这些变更也只需要在内部作出调整即可。

Why

为什么?

How

怎么办?

Resources

更多资料

Interface Segregation Principle

接口隔离原则

Reduce fat interfaces into multiple smaller and more specific client specific interfaces. An interface should be more dependent on the code that calls it than the code that implements it.

降低接口的粒度,使得接口更小更具体,更接近调用方的现实需要。一个接口的定义更多地应该依赖于调用方的代码,而不是实现方可以实现的细节。

Why

为什么?

How

怎么办?

Resources

更多资料

Command Query Separation

命令查询职责分离(也称Command Query Responsibility Segregation,CQRS)

The Command Query Separation principle states that each method should be either a command that performs an action or a query that returns data to the caller but not both. Asking a question should not modify the answer.

命令查询职责分离准则的具体阐述可以参见资料所引述到的Martin Fowler的文章。命令查询职责分离原则指出,每个方法应该是执行一个操作的命令(命令是void的,不返回任何结果,但会改变对象的状态)或者一个查询(返回结果,但是不会改变对象的状态,对系统没有副作用),它将数据返回给调用者,而不是两者。提出问题不应该修改答案。

With this principle applied the programmer can code with much more confidence. The query methods can be used anywhere and in any order since they do not mutate the state. With commands one has to be more careful.

使用这条准则,程序员在编码之时可以更加自信,查询方法可以在任何地方以任意次序使用,因为它不会影响到对象状态。而命令则需要更加小心谨慎。

Why

为什么?

How

怎么办?

Resources

更多资料