【翻译】我的软件工程原理

416 阅读22分钟

译者注

这篇文章写的真的很好,适合每个软件行业从业者读读。可惜本人水平有限,翻译很生涩,希望大家读读原文。


几个月前,我在一次演讲中分享了我的软件工程原理—多年来,我一直认为,在编写代码、构建东西以及与他人合作时,这些axiom列表通常都是正确且有用的。

AXiom是一个很复杂的词,来源于古希腊语,或者说是“想法正确的且值得的”。我喜欢这一点,并且认为清单上的每一项至少都值得考虑。。

当然,它们是我的工程公理-根据我自己的经验,我认为这些都是有用的。你的经验可能会有所不同。可能你已经知道Zero termination,或者有更好的工具去修改程序中的bug.

无论如何,我认为在这里分享这个列表会很有趣,并做一些简短的澄清:有些axiom并不让人惊讶,但也有希望产生一些挑衅的想法和/或有趣的分歧。

A few months back I gave a talk in which I shared a list of my personal engineering axioms – things that, over the years, I've come to think of as generally true and useful to have in mind when writing code, building things, and working with others.

Axiom is a fancy word, but popping a few layers off the etymology stack we arrive neatly at the ancient Greek word ἀξίωμα, or "that which is thought fit or worthy". I like that, and consider each item on the list at least worthy of consideration.

Of course they're my engineering axioms – things I believe to be useful based on my own experience. Your experience may well differ. Maybe you already knew about zero termination, or have better tools than scissors to remove bugs from your programs. In any case, I thought it would be fun to share the list here, with a few brief clarifications. Some things are pretty unsurprising, but hopefully others will generate some provocative thoughts and/or interesting disagreements.

1. 变化是不断的。

这一条应该没什么争议。几乎所有的事物都在变化,包括变化的速率本身。应对变化的能力是至关重要的,而且我们做得如何(时间、成本、质量、可靠性)往往是我们竞争力的一个方面。

  1. Change is constant. This one shouldn't be too controversial. Almost everything is always changing, including the rate of change itself. We need to acknowledge not only that our ability to respond to change is crucial, but that how well we do it (time, cost, quality, reliability) is often a dimension of our competitiveness.

2. 产品是资产,代码是负债

产品解决了客户的问题,因此是资产。代码是创建资产的成本。写的代码越多,需要阅读,测试,更改和理解的成本也会增多。当考虑到axiom1时,这一点尤其相关。保守地接受新代码(以及对外部代码的依赖)。最好的代码是不需要写代码。

2. Your product is an asset, but code is a liability. Your product solves your customer's problem(s), and therefore is your asset. The code itself is the cost of creating the asset. The more code you have, the more it needs to be read, tested, changed, and understood. This is especially relevant when you consider axiom 1. Accept new code (and dependency on external code) conservatively. The best code is code you don't have to write.

3. 复制粘贴比过早的抽象成本低。

除非你非常确信抽象可以解决问题,否则不要这样做。再等等并且坚持学习。在此之前,重复代码可以帮助避免相互依赖,降低耦合度。过早的抽象通过依赖性和间接性产生复杂性,并可能成为修改代码时的瓶颈。

  1. Duplication is less costly than premature abstraction. Until you have a high degree of confidence that your abstraction is going to pay for itself because it solves a real, abstract problem you really do have, don't do it. Wait and learn more. Until then, repeating code can help avoid dependency, which itself makes the code easier to change independently or delete. A premature abstraction creates complexity through dependency and indirection, and can become a bottleneck to your ability to respond to change.

4. 代码应易于删除。

编写可删除的代码,即常说的解耦。当然,并不是所有的代码都需要可移除性,但是最小化依赖、通过定义良好的接口拥有明确的边界、以及具有深思熟虑的整体系统设计可以让代码更容易地删除/变动。我曾经听到有人用“代码消耗”来代替“代码编写”,我很喜欢这个说法,这暗示着删除代码可以减少未来的成本。

  1. Code should be easy to delete. Write code to be removable, which in large part is the same as saying "decoupled". For sure not all code needs to be similarly removable, but minimising dependencies, having clear boundaries via well-defined interfaces, and having a thoughtful overall system design allows parts to be removed/changed more easily. I once heard someone use the expression "code spent", as an alternative to "code written" and I love that. I like the implication that removing code is reducing future cost.

5. 现有的代码具有强大的影响力。

现有的代码表示它是正确和必要的。我很希望是这样,但并非总是如此。我们需要有改现有的代码的能力,也要有能力去判断是否应该改它。不要让人怀疑这代码无法删除。根据axiom4,它应该容易移除,并且系统设计应该足够好,让我们知道是否还需要它。

5. Existing code exerts a powerful influence. The very fact it's there suggests it's correct and necessary. Hopefully it is, but not always. We need to maintain both the confidence to change it, and the ability to reason about whether we should. Don't let the existence of code itself create doubt that it can't be removed. As per axiom 4, it should be easy to remove, and the system design should be good enough to enable us to understand whether we still need it.

6. 意外的复杂度是最大的风险之一。

意外复杂度是可以避免的,它的出现是由于糟糕的设计、错误的决策,以及没有在系统中按简易程度进行优先级排序。如果简单性不是一个目标,那么随着系统的发展,意外复杂度更有可能发生,这对修改代码甚至理解代码都会产生消极影响。关于这一主题,2006年的论文《Out of the Tar Pit 》值得一读。

  1. Accidental complexity is one of the biggest risks. Accidental complexity is complexity that can be avoided, and occurs due to things like poor design, bad decisions, and not prioritising an appropriate level of simplicity within a system. If simplicity is not a goal, accidental complexity is more likely to occur as a system grows, and will gradually negatively affect almost everything from changing the system to even being able to understand it. The 2006 paper Out of the Tar Pit is a worthwhile read on this subject.

7. 糟糕的人际关系可能会掩盖技术的卓越。

除非是完全独立工作,否则重要的不只是解决技术问题的能力和编写优秀代码的能力。人际关系不好会使生产力降低。就像学习编写好的代码一样,你也必须学习“对人”好。同理心是其中很重要的一部分,关心,理解,互相帮助,对人友善。成为其他人想要与之共事的工程师。

  1. Technical excellence can be shadowed by bad personal skills. Unless you're working completely alone, it's not just your ability to solve technical problems, to write good code, etc, that matters. To the contrary, they matter even less if you make the people around you unhappy and less productive. Just like learning to write good code, you have to learn "to people" good as well. Empathy is a big part of this, as is recognising that people are different – be caring, be understanding, help others and ask for help yourself, be nice. Be an engineer others want to work with.

8. 你不是你的代码。善待程序员,而不是代码。

你写下的代码表示那一瞬间你的思想和知识水平,而不是你本身。你写下这行代码(即使是3分钟以前),你成长了,但代码却没有。代码的好坏绝对不牵扯到个人。把它当成是职业。可以谈论代码或者问题,但是不要谈论写代码的人。使用“我们”来代替“ 你”。有时我会试着假装别人写的代码是我写的,这有助于我避免牵扯到个人。

8. You are not your code. Be kind to the coder, not to the code. Code is merely a moment in time that captured what we thought we knew about something. It's not you. You may have wrote it, but since that moment (even if it was 3 minutes ago) you've grown, but the code has not. A conversation about code, good or bad, should never be personal. Keep it professional. Talk about the code, or about the problem, but don't make it about the person who wrote it. Use "we" instead of "you". Sometimes I try to pretend I wrote the code someone else wrote, which helps me avoid accidentally sounding personal.

9. 尊重和耐心地对待比你了解得少的人。

刚入行时,当你被希望你成功并且耐心的人包围着,而不是让那些让您觉得自己不属于这里的陪伴时,旅程会更加快乐。如果你纠结于这一点,记住这些可能会有所帮助:新手程序员在某些方面肯定比你做得更好,他们可能精通另一种语言,或者烹饪非常出色,或者精通体育运动。如果你是一个新手,您希望他们如何对待你? 再次重申一下:成为其他人想要与之合作的工程师。

9. Treat people who know less than you with respect and patience. We all start somewhere, and the journey is a lot more joyful when you're surrounded by patient people who want you to succeed, rather than those who make you feel like you don't belong. If you struggle with this, it may be helpful to remember that the newbie programmer almost certainly does something better than you do – perhaps they're fluent in another language, or cook amazingly, or play a sport. Just imagine yourself in the reverse role. How would you like them to treat you, the total newbie? Again: be an engineer others want to work with.

10. 真正的权威来自知识,而不是地位

对问题,领域,客户的了解比名片上的身份都重要得多。扎实基础,了解原理,强化理解,权威就会随之而来。

10. The only true authority stems from knowledge, not from position. Knowledge and understanding of the problem, the domain, the customer, are all far more important than whatever the first 3 letters on your business card are. Even if it does have a watermark. Understand how something works from first principles, build a solid understanding, and authority will follow.

11. 教也是学

如果你认为你学会了新知识,那么试着去教会别人。通常,试图向别人解释你会的知识时会迫使你理清思路。记笔记写博客也有类似的效果。记不清有多少次当我开始解释一些东西时,结果却发现我并没有想象中那么理解它。

11. Teaching is a form of learning in disguise. If you think you know something, try teaching it. Often the very act of trying to explain what you know to someone else forces you to formalise your own thoughts much more clearly. Writing things down seems to have a similar effect. I've lost count of the number of times I've begun explaining something only to find I don't quite understand it as well as I thought.

12. 提升你周围的人的技能,而不仅仅是你自己。

一个好的团队不是因为有一个优秀的成员,而是团队成员相互学习,共同成长。当你学到一些很棒的东西时,请与他人分享——帮助周围的人变得更好。 互帮互助乐于分享,每个人都会受益,没有人会掉队。 这也会更有趣。 与人分享也可以加深自己的理解。

12. Lift the skills of people around you, not just yourself. A great team is never a great because of one amazing person. It's a great team because everyone challenges each other and everybody grows together. When you learn something cool, share it – help the people around you get better. As they do the same, everybody benefits and nobody gets left behind. It's also far more fun. Secondary benefit: axiom 11.

13. 等得越久,你知道的就越多。

我仍在学习这一点,并努力克制自己快速做决定。事实是,延迟做不必要的决定,你就会有更多的信息来帮助你做出决定。当然,你不能总是拖延做决定,但你应该考虑一下现在不做决定是不是真的可以。

  1. The longer you wait the more you'll know. I'm still learning this and trying hard to avoid my almost default desire to decide quickly. The truth is, the longer you delay non-essential decisions the more information you'll have to lean on when the time comes to make it. Of course you can't always procrastinate a decision, but often you can, and as a minimum you should at least consider whether not knowing the answer right now is actually OK.

14.一个好的类型系统是值得他的开销的。

在我的职业生涯中,我前后经历了各种静态和动态语言,目前我认为一个好的类型系统是值得它的开销的。如果类型系统设计得好,它几乎可以让人感觉像一门动态语言(通过推理和流程分析等特性),同时消除了编译器可以比你更好更快地处理的一类问题。Rust的发展就是一个很好的例子,它比人们多年前想象的发展得更远。

14. A good type system is worth its weight plus some. Having gone backwards and forwards through various static and dynamic languages over my career, I'm currently of the opinion that a good type system is worth its overhead. A good type system shouldn't carry all that much overhead. If the type system is designed well, it can almost feel like a dynamic language (via features like inference and flow analysis) while removing a whole class of issues that the compiler can handle far better and quicker than you can. Developments like ownership in Rust are a nice example of how this has gone even further than people would have imagined years back.

15. 合适的团队胜过其他一切

与一群志同道合的同事相处,会让很多其他问题更容易处理。“合适”这个词在这里是非常主观的,但有趣,共鸣、尊重和友谊是我所参与的好团队中反复出现的元素。

15. The right team of people trumps everything else. Having a team of people who just want to work together and build great things makes a lot of other problems easier to deal with. The word "right" here is highly subjective and contextual, but at least anecdotally, empathy, respect, and friendship have been recurring elements of great teams I've been part of.

16. 坚持使用成熟的技术,除非有充分的理由不这么做

旧的技术往往更成熟,更容易理解。在如何有效使用它,如何更好地了解它的bug方面有很多先例,并且更容易找到人和资源来更好地使用它。我很喜欢Dan McKinley的innovation tokens的想法。你只有3个代币,使用它们来采用或建立全新的东西——理想情况下,这些东西会让你在核心竞争力上做得更好——但是超过3个,不稳定/不成熟的风险开始增长。

16. Stick to boring technology, unless there's a good reason not to. Boring tech is often older and better understood. There's battle-hardened experience of how to use it effectively, better understanding of its failure modes, and it's easier to find people and resources on how to best apply it. I really like Dan McKinley's idea of innovation tokens. You only get 3. Use them to adopt or build brand new stuff – ideally stuff that will make you better at your core competency – but any more than 3 and the risk of never reaching stability/maturity starts to grow.

17. 尽可能让团队最小化。

在我的职业生涯中,我确实看到过小团队比大团队更有效率。当然,这取决于你要解决的问题的规模和复杂性,我们需要找到一个平衡点。较小的团队受益于更少的沟通开销,更少的误解,每个人的声音可以被听到。在一个较小的团队中,这也会让人感觉更个性化,责任感会更强。

17. Have the smallest team possible, but no smaller. Grow it carefully. A play on a well-known quote, and your mileage may vary on this one. In my career so far, I've reliably seen smaller teams be more effective than larger ones. There's a balance to be found, for sure, which depends on the magnitude and complexity of the problem you're solving. That said, smaller teams benefit from less communication overhead, less room for miscommunication, and more space for everyone's voice to be heard. In a smaller team, it also feels more personal, and I feel more responsible, and I like that.

18. 休息

我很高兴地看到 "为了成功而不惜一切时间工作 "的态度逐渐淡化,人们对心理健康和幸福感的关注度大大提高。当你休息不足的时候,你很难感觉到快乐,而当你感觉不到快乐的时候,你更难做好工作。为了以最佳状态工作,我们必须花时间休息。我喜欢把休息看作是我工作能力的一个关键部分,就像体育锻炼一样。

18. Rest. I'm happy to see the gradual de-sexification of the "work all hours to be successful" attitude, and far more attention being put on mental health and well-being. It's incredibly difficult to feel happy when you don't feel rested, and it's even more difficult to do your best work when you're not feeling happy. To work at our best, we have to spend time not working. I like to think of rest as a key part of my ability to work, in the same way it is for physical exercise.

19. 在你想到至少一个解决方案之前,不要选择解决方案

当你找到了解决问题的方法时,你会觉得很兴奋。当面对小问题时,这就够了,也不用再多做什么。然而,如果这个问题是至关重要的,那么就值得考虑可能还有其他还没有想到的解决方案。为了避免从没有思路到有解决方案的兴奋中被冲昏头脑,而只是按照你头脑中的第一想法去做,试着再想至少一个。试图找到第二种解决方案往往会迫使你以不同的方式思考,一旦你有了两种解决方案,你就不得不权衡取舍,选择其中一种。这种相互取舍的权衡通常也可以帮助更清晰地解决问题。

19. Don't pick a solution until you've thought of at least one more. It's enticing and exciting when that thing clicks in your head and you realise you found a way to solve the problem. Perhaps with a trivial problem that's cool and there's really nothing more to do. However, if the problem is non-trivial or important, it's worth considering that there may be other solutions you simply haven't thought of yet.

To avoid getting carried away in the excitement of going from no solution to a solution, and simply going with the first thing that comes into your head, try to think of at least 1 more. Trying to find a second solution often forces you to think differently, and once you have two you'll be forced to consider the trade-offs in order to select one. Such contrasting trade-offs can often help frame the problem more clearly as well.

20. 要有主见,但话不要说得太满

表达观点很重要,我们都有这样的权力。但是,在分享意见和发表意见之间存在界线,发表意见就像你在说一个不可动摇的事实一样。在一个团队中,让每个人都觉得自己可以挑战别人的观点,并有可能改变它,或者改变自己的观点,这是非常有益的。

在这方面,我收到的一个很有帮助的建议是,表达你的观点,以及你的肯定程度: “我有95%的把握使用Visual Basic是个坏主意。“即使是95%,这对别人来说都是一个可以质疑并创造对话的机会,对你来说也是一个机会,当你了解到新信息时,可以很简单地修改你的肯定度。

20. Have opinions, but avoid expressing them in ways that cause other people to believe you won't change them. Expressing our beliefs and opinions is important, and we should all have the room to do that. However, there's a fine line between sharing an opinion and sounding as though you're sharing an immovable fact. In a team, it's incredibly healthy for everyone to feel like they can challenge an opinion and potentially change it, or their own.

A great piece of advice I received that helps with this is to express your beliefs along with a percentage of how sure you are. "I'm 95% sure using Visual Basic is a bad idea." Even when it's 95%, it's both an opening for someone to question the belief and create a conversation, and an opportunity for you to simply revise your sureness if new information is learned.

21. 你可以说“我不知道”或“我需要调研一下”。

我们的行业发展迅速,虽然有很多新的老知识,但也有大量的新知识。我们每天都在学习,暂时没有解决方案也没关系。我们的价值不是我们什么问题都知道,而是我们学习、发现、回答这些问题和创造新问题的能力。

当有人告诉我“我不知道”时,我很高兴,因为现在我知道我们可以一起探索这个问题,并且都能学到一些东西。不要掩饰你的不知道,通常别人也不知道,但你的诚实让每个人都能参与并一起去探索。

21. It's OK to say "I don't know" or "I need to research that before I have an answer". Let's be honest, none of us have a clue what we're doing. You do? OK, well I don't. Our industry moves quickly, and while there's lots of new old things, there's a healthy amount of new new things as well. We're all learning every day, and not having an answer is absolutely fine. Our value is not our ability to know everything, it's our ability to learn, to find out, to answer those questions and create new ones.

I'm excited when someone tells me "I don't know" because now I know we can explore the problem together and both learn something. Don't hide it as though you're the only one who doesn't know. Often nobody knows, but your honesty just enabled everyone to join in openly and work together.

22. 不断探索尝试解决问题

试错几次然后重新开始比试图第一次就做对要快得多。有时,解决问题的最佳方法是不断探索,并尽可能多地学习。

也许你还没有真正理解问题所在,但通过尝试,你可以发现关于设计的高层次对话或阅读文档中完全错过的东西。你可以自由地试错,然后在最后把它们都丢掉,这样可以很快学到东西。

22. Writing throwaway code to explore a problem space is underrated. It can be quicker to get it completely wrong a few times and start over than to attempt to get it right first time. Sometimes the best way to explore the problem is by screwing around very close to it and learning as much as you can.

Perhaps you don't really understand the problem space yet, but by trying a few things out you can discover stuff that high level conversations about design, or reading docs will completely miss. With the freedom to make as many mistakes as you like and throw it all away at the end, you can learn very quickly.

23. 小心地管理状态

每个程序都有状态,但是如何管理这种状态会产生很大的不同。糟糕的状态管理是导致整个系统复杂性的一个巨大因素。

有许多不同的策略可以提供帮助,从特定的方法来处理给定环境中的状态,到使用函数式语言和/或方法来创建关于状态如何改变的更严格的约束。无论你做什么,都要仔细考虑系统中的状态如何变化。

23. Manage state carefully. Every program has state, but how that state is managed can make a world of difference. Poor management of state is a huge contributing factor to overall system complexity, and often occurs because it hasn't been thought about early enough, before it grew into a much worse version of the problem.

There are lots of different strategies to help, from particular approaches to handling state in a given environment, to using functional languages and/or approaches to create tighter constraints around how state can change. Whatever you do, be deliberate about how state in your system changes.

24. 权衡

几乎你做的每一个决定,你都是有意或无意地进行权衡折衷。有时权衡是显而易见的,但有时,它们与我们眼前能看到的东西是有层次之分的。如果权衡取舍不是很明显的话始终要思考如何权衡折中。

我想到的一个好例子是Go。Go有一个相当糟糕的类型系统(目前),而且它是一个轻量的语言。取舍是什么呢?由于它的大小,以及对花哨的支持有限,我的代码看起来就像你的代码,我读别人的代码时,比以前少了 "哇,我需要尽快重写这个 "的感觉,而且我觉得效率高多了。总会有一些地方是需要权衡的。寻找它,你就能做出更好的决定。

24. It's all about trade-offs. With almost every decision you make, you're either deliberately or accidentally trading off one thing for another thing. Sometimes the trade-offs are obvious, but sometimes they are layers away from the thing we can see in front of us. Always be thinking about where the trade-offs may be if they're not immediately obvious.

A good example that comes to mind is Go. Go has a fairly poor type system (currently), and it's a tiny language. What's the trade-off? Due to its size, and limited support for fanciness, my code looks like your code and I read other people's code with less "wow, I need to rewrite this ASAP" than ever before and I feel far more productive. There's always a trade-off somewhere. Look for it and you'll be in a position to make better decisions.

25. 好的设计是你可以改变你的想法,但不需要改变太多的代码。

如axiom1, 变化是不断的。这意味着我们需要很好地处理不断变化的情况,不仅要面对外部变动,还有来自pivots、新特性、可拓展等的内部变化。好的系统设计应该尽可能地满足需求的变动,而不是迫使我们从头开始。换句话说,代码耦合度越低(根据axiom4,这应该是很容易的),我们在面对改变时就能行动得越快,设计得越好。

25. A good design is one in which you can change your mind without changing too much code. As per axiom 1, change is constant. That implies that we need to handle changing conditions well to succeed – not just external change that occurs around us and takes us along for the ride, but also the internal change that come from pivots, new features, scaling challenges, etc.

A good system design should accommodate, as much as possible, our need to change how we approach the problem without forcing us to start over from scratch. In other words, the fewer parts we have to change or remove (which should be easy as per axiom 4), the quicker we can move in the face of change; the better the design.

原文链接

martinrue.com/my-engineer…