我什么时候需要停止使用设计模式?
我的同事们都快疯了,因为我一直想重写已经可以工作的代码,因为我想用设计模式替换一些遗留设计。虽然我觉得这将有助于改进现有代码,但我确实觉得我对此有点偏执,并尝试在任何地方使用它们,甚至用另一种设计模式替换一种设计模式。我的一些同事说,只要遗留代码可以工作,就不要管它。
我什么时候应该停止使用它们?需要用更好的设计替换的代码和不需要修改的代码之间的界限在哪里?
My colleagues are going crazy because I keep on wanting to rewrite code that already works, because I would like to replace some legacy design with design patterns. Although I feel like it will help improving the existing code, I do feel like I am getting a little paranoid about it and try to use them everywhere and even replacing one design pattern with another. Some of my colleagues say that so long as the legacy code works, leave it alone.
When should I stop using them? Where do you draw the line between code that needs to be replaced by a better design and the one that needs to not be touched?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
通常,Gof4 设计模式涉及添加一定程度的间接性,以便更轻松地更改任意一侧。如果事情不会改变/不需要变得更加灵活,那么您就不需要这种间接方式。如果它已经存在并且正在工作,则无需更改。重定向级别不是免费的,而是会降低性能并增加复杂性。如果我没记错的话,GofF 作者自己也指出了这一点。
编辑添加:好的,必须去拿书才能找到确切的报价。它位于第 31 页介绍的末尾,至少在我的版本中是这样:
Typically, Gof4 design patterns involve adding some level of indirection to make changing either side of it easier. If things aren't going to change / don't need to be made more flexible, then you don't need that indirection. If it's already there and working, no need to change. Levels of redirection are not free but have costs in terms of performance and added complexity. The GofF authors themselves pointed this out if I remember correctly.
Editing to add: OK, had to go and get the book to find the exact quote. It's at the end of the introduction on page 31, at least in the edition I have:
通过触摸代码,您会产生一旦工作代码将停止正常工作的风险。更好地利用您的时间可能是确保单元测试覆盖遗留代码。然后,当需要更改代码时,您可以重构为任何合适的模式,并确保代码仍然按照设计的方式工作。
By touching the code, you create risk that once working code will stop working correctly. A better use of your time might be to make sure that the legacy code is covered by unit tests. Then when the need arises to change the code, you can refactor to whatever pattern is appropriate, and ensure that the code still works as it was designed to.
当您重构时,您可以考虑重构设计模式,但是如果代码已经在工作,那么仅仅为了设计模式而更改代码是没有意义的。
When you refactor then you can look at refactoring to design patterns, but there is no point in changing code just for design patterns, if it is already working.
我同意 Joel Spolsky 的观点,重写代码几乎总是一个坏主意,除非你有非常非常具体地了解现有代码有什么问题,重写它会改进什么,以及重写它可能会失去哪些知识。
“重写代码,因为它冒犯了你的感情”,说实话,是一个非常糟糕的主意。这是对你时间的浪费,而且有可能破坏你不理解的东西。
您重写的每一行代码都可能(并且根据我的经验,很可能)引入到代码库中的新错误。永远不要重写代码,除非您有当前且令人信服的理由这样做。
I concur with Joel Spolsky that rewriting code is almost always a bad idea unless you have a very, very specific idea of what is wrong with the existing code, what rewriting it will improve, and what knowledge you are likely to lose by rewriting it.
"Rewriting code because it offends your sensibilities" is, seriously, a teribly bad idea. It's a poor use of your time, and it runs the risk of breaking something that you didn't understand.
Every line of code that you rewrite is potentially (and, in my experience, likely) a new bug that you are introducing to the codebase. Don't ever rewrite code unless you have a present and compelling reason to do so.
如果你是我的同事,我也会发疯的。设计模式只是一些如何解决问题的一般想法。它们不是主从山顶上用泥版传下来的话语。
If you were my colleague, I would be going crazy too. Design patterns are just some general ideas for how to go about solving problems. They are not the word of the Lord sent down from the mountaintop on clay tablets.
我认为你提出这个问题非常好,这是迈向 DPW(设计模式撤回)的第一步。
听起来你有典型的上瘾迹象,现在是时候退后一步,检查你的编码生活,并问这样的问题,这是否影响了我的同事?我的公司是否因为我的习惯而遭受损失?
经过反思和检查,也许您可以找到一种方法来调节您的设计模式的使用,并用健康的模式替换破坏性的模式,这给您和您的编码团队带来好处。
一些有用的提问可能是,您使用设计模式仅仅是因为您昨晚读到了新的设计模式,还是因为您认为它可能为项目增加真正的价值?您是否因为强烈的愿望而在代码中强制使用设计模式,或者因为该模式的真正用处已经出现?代码是否已经运行良好并且不会很快更新?如果是这样,可能会有更好的地方来消磨时间。
最后,您可以尝试尝试完全放手,看看您编写的代码中会出现什么自然的“模式”,而不是试图强迫代码适应您关于它应该如何的想法。通过这种方式,你可能会发现自己的“模式”。
祝你好运,我想我们中的许多人都以某种方式经历过这种情况,请记住,如果你旧病复发,你总是可以依靠你的支持网络(和常识)来依靠。
I think it's very good that you've asked the question, that's the first step towards DPW (design pattern withdrawal).
It sounds like you have the classic signs of addiction, now is the time to step back and examine your coding life, and ask things like, is this affecting my co-workers? Is my company suffering because of my habit?
Upon reflection and examination, perhaps you can find a way to moderate your design pattern use, and replace the destructive patterns with healthy ones, that bring benefits to you and your coding team.
Some helpful lines of questioning might be, do you use design patterns just because you read about a new one last night, or because you think it might add genuine value to the project? Do you force a design pattern on the code due to your strong desires, or because a real usefulness for the pattern has emerged? Does the code already work well and won't be updated anytime soon? If so, there might be better places to spend your time.
Finally, you might try experimenting with completely letting go and see what natural "patterns" emerge from the code you write, rather than trying to force the code to adapt to your ideas about how it should be. You may discover your own "patterns" this way.
Good luck, I think many of us have been there in one way or another, remember you always have your support network on SO (and common sense) to fall-back on if you have a relapse.
不要强制重新设计 - 仅根据需要重构代码,尤其是在代码已经正常工作的情况下。你改变的越多,你需要测试的就越多。如果没有现有的测试,这意味着(无论如何,在完美的世界中)您必须编写测试。
相反,集中精力清理小块的代码,只做必须做的事情。当您进行时,为您接触的类编写或更新单元测试,以确保一切继续正常工作。
Don't force a redesign - only refactor code as you need to, especially if the code already works properly. The more you change, the more you will have to test. And if there aren't existing tests, this means (in a perfect world, anyway) that you would have to write the tests.
Instead, focus on cleaning up code in small chunks, only doing what has to be done. As you go, write or update unit tests for the classes that you touch to make sure everything continues to work as it should.
对于个人项目,让自己精疲力尽。
为了专业工作,停下来吧!您正在浪费资源,您可能正在完成请求的功能。另外,您确定在更改旧代码时 100% 翻译它吗?如果没有,你就会产生问题,甚至可能产生新的错误。
for personal projects, knock yourself out.
for perfessional jobs, stop it! you are wasting resources, you could be completing requested functionality. alos, are you sure you are translating the old code 100% when you change it. if not, you are creating problems and possibly new bugs.
不需要时不要过度设计。不过,我自己花了一些时间来学习这一点。
问问自己何时需要使用特定的设计模式。当情况并非如此时,就不要这样做。在遗留系统上使用设计模式的一个很好的理由是在重构过程中。
Don't over-engineer when it's not needed. Took some time for me to learn this myself, though.
Ask yourself when it is needed to use a particular design pattern. When it's not the case, don't. A good reason to make use of design patterns on a legacy system is during refactoring.
Joel Spolsky 在他的博客上相当聪明地讨论了这个问题。
本质上,一段代码越旧,它就越有可能经过彻底的测试和调试;即使它充满了奇怪的修复和你认为是黑客的东西,它们很可能是有充分理由的。因此,无论设计多么冒犯您,都请避免重写代码,除非该代码确实被破坏了。
Joel Spolsky discussed this rather intelligently on his blog.
Essentially, the older a piece of code is, the more likely that it's been thoroughly tested and debugged; even if it's full of weird fixes and things that you think are hacks, it's likely that there's a good reason for them. So avoid rewriting code no matter how much the design offends you, unless that code is definitively broken.
我采用“金钱”方法。重写现有代码会花费您雇主的钱(您的工资等)。你能诚实地说,你的重写会给你的雇主带来比保持原样更少的成本吗?根据我的经验,答案几乎总是“不”。
我遇到过不少这样的人,他们量化成本的能力很差,从来没有给予任何理性的考虑,或者更关心他们直接获取薪水的愿望,而不是为雇主提供良好的价值。我个人发现,好的雇主会认识到你正在帮助他们,并且随着时间的推移会相信你的判断。
I go with the "money" method. Rewriting existing code costs your employer money (your salary, etc.). Can you honestly say that your rewrite will cost your employer less than leaving it the way it is? In my experience the answer is almost always "no".
I've met more than a few whose ability to quantify cost was poor, never gave it any rational consideration, or cared more about their immediate desire to extract a paycheck than delivering good value to their employer. I personally have found good employers will come to recognize you're helping them and will come to trust your judgment over time.
大多数程序员都有一个客户,他们基本上支付程序员的工资。
当你想到要做出这样的改变时,问问自己,“如果我让客户理解了所涉及的问题,他会希望我花时间在这上面吗?”。通常情况下,答案是否定的。为什么他们会关心它是否有效?
Most programmers have a customer somewhere along the line, who is essentially paying the programmer's salary.
When it occurs to you to make a change like this, ask yourself, "If I made the customer understand the issues involved, would he want me to spend time on this?". Much more often than not, the answer is no. Why would they care if it works?
当你没有客户时,我不同意每个人的观点。
重新设计、批评、改进你的代码会让你变得更好。
如果你从不想回顾自己所做的事情,那么你就不会进步,你需要批评自己。
即使后来您发现重新设计是一个坏主意,您也会明白原因。
I disagree with everyone when you don't have a customer.
Redesigning, criticizing, improving your code is what make you better.
If you never want to retrospect on what you did, then you won't improve, you need to criticize yourself.
Even if later you see that it was a bad idea to redesign, you'll learn why.
我经常发现自己使用“总是让一段代码处于比你发现它更好的状态”的原则。
因此,如果我加载一些类并注意到在我开始执行更改请求之前它可以进行一些春季大扫除,那么我将首先执行此操作。这还有另一个优点,因为它可以为您提供一种阅读和理解代码及其依赖项等的方式。
我发现执行更改请求要简单得多,因为您可以更好地理解代码。
最后,您将获得两全其美的好处……一位满意的客户和一个更满意的代码库。
Quite often I find myself using the "always leave a piece of code in a better state than what you found it" principle.
So if I load up some class and notice it could do with a bit of a spring clean before I set about doing the change request, then I will do that first. This also has another advantage in that it doubles-up for you as a way to read and understand the code and its dependencies etc.
I find that then doing the change request is much simpler because you understand the code better.
And then at the end of it all you have the best of both worlds... one happy customer and one happier code base.
交易不同的设计模式而没有任何收益是一个失败的提议。设计应用程序时,请使用您认为正确的设计模式并坚持下去,除非有明显的理由需要更改该模式。我建议听听同事的意见,不要管这个应用程序。
Trading different design patterns for no gain is a losing proposition. When designing an app use what you believe will be the proper design pattern and stick with it unless there are obvious reasons to change the pattern. I suggest listening to your coworkers and leaving this app alone.
我不认为“如果它没有坏,就不要修理它”是正确的。我认为您绝对应该寻找可以重构的代码,以切实的方式使其变得更好。问题是 - 确保你正在做的事情对未来有帮助,并且它有帮助的部分是具体的。
用设计模式术语来说——设计模式可以帮助您使代码在面对变化时更加健壮——它允许代码的某些部分独立于其他部分而变化。想想是否有特定的原因需要更改某些内容 - 您是否预计将来对某些代码进行更改需要涉及许多其他子系统?
如果你清楚地说明了你正在解决的问题,并且你能够说服自己和你的同事这个问题值得解决(即未来的好处是显而易见的),那么你应该能够继续前进。
I don't think "If it ain't broke, don't fix it" is right. I think you should definitely be on the lookout for code that can be refactored to make it better in a tangible way. The thing is - make sure you are doing something that will help in the future, and the part where it helps is concrete.
In design pattern terms - design patterns help you make your code more robust in the face of changes - it allows some parts of the code to vary independently of others. Think whether there is a specific reason to change something - do you anticipate future changes to some piece of code that will require touching a lot of other subsystems?
If you're clearly stating the problem you are fixing, and you are able to convince yourself and your colleagues that the problem is worth fixing (i.e. future benefit is obvious), then you should be able to move forward with it.
如果代码可以工作,并且不需要关注 - 不要花费时间/金钱来更新它。除非财政上有必要这样做。只要确保所有新代码都是优秀的,然后从现在开始慢慢消除这个问题。
If the code is working, and doesn't need attention - don't spend time/money updating it. Not until it is fiscally-necessary to do so. Just make sure all of your new code is excellent, and slowly erase this issue from now on.
这是一个给您的启发:您接触的代码在生产环境中没有出现问题的时间越长,更改它所承担的风险就越大。鉴于此,您能评估您正在做的事情的真正价值吗?您是否正在使代码变得更好?表现更好?更易于维护?您必须量化所做更改的好处,并在其与重构风险之间进行权衡。不管愿意与否,重构通常是一个错误。您应该有充分的理由这样做,并且您应该能够量化收益。
想象一下,您的老板将您带到他/她的办公室,并问您“代码没有问题的情况下,为什么要进行此更改?”你会有好的答案吗?
根据评论:我在此 所以回答。
Here's a heuristic for you: the longer the code you touch has been in production without issues, the more risk you take by changing it. Given that, can you assess the true value of what you're doing? Are you making the code better? Perform better? Be more maintainable? You must quantify the benefit of the changes you are making and balance them against the risk of the refactor. Willy-nilly refactoring in general is a mistake. You should have a very good reason to do it and you should be able to quantify the benefit.
Just imagine your boss brings you into his/her office and asks you "why did you make this change when there was no problem with the code?" Will you have a good answer?
Per comment: I provide some good resources for Cost of Quality (COQ) and Cost of Non Quality (CNQ) in this SO Answer.