克服“稍后修复”的坏习惯

发布于 2024-07-27 23:29:08 字数 443 浏览 4 评论 0原文

当我从头开始编写代码时,我有一个坏习惯,即在一个函数中快速编写所有内容,一直在想“稍后我将使其更加模块化”。 然后当后来出现时,我有一个工作产品,任何修复它的尝试都意味着创建函数并必须弄清楚我需要传递什么。

情况变得更糟,因为当您的项目即将完成时,重新设计类变得极其困难。 例如,我通常在开始编写代码之前做一些计划,然后当我的项目完成时,我意识到我可以使类更加模块化和/或者我可以使用继承。 基本上,我认为我没有做足够的规划,也没有得到超过一层的抽象。

所以最后,我陷入了一个具有大型主函数、一个类和一些辅助函数的程序。 不用说,它的可重用性不太好。

有没有人遇到过同样的问题并且有什么技巧可以克服这个问题? 我想到的一件事是用伪代码编写主函数(没有太多细节,但足以看出他们需要什么对象和函数)。 本质上是一种自上而下的方法。

这是一个好主意吗? 还有其他建议吗?

When I start writing code from scratch, I have a bad habit of quickly writing everything in one function, the whole time thinking "I'll make it more modular later". Then when later comes along, I have a working product and any attempts to fix it would mean creating functions and having to figure out what I need to pass.

It gets worst because it becomes extremely difficult to redesign classes when your project is almost done. For example, I usually do some planning before I start writing code, then when my project is done, I realized I could have made the classes more modular and/or I could have used inheritance. Basically, I don't think I do enough planning and I don't get more than one-level of abstraction.

So in the end, I'm stuck with a program with a large main function, one class and a few helper functions. Needless to say, it is not very reusable.

Has anybody had the same problem and have any tips to overcome this? One thing I had in mind was to write the main function with pseduocode (without much detail but enough to see what objects and functions they need). Essentially a top-down approach.

Is this a good idea? Any other suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

南城追梦 2024-08-03 23:29:09

我发现 TDD 红绿重构规则非常有效。

I find the TDD Red-Green-Refactor discipline works wonders.

夜灵血窟げ 2024-08-03 23:29:09

我的经验法则是任何超过 20 LoC 的东西都应该是干净的。 IME 每个项目都基于一些“只是概念验证”,而这些“概念验证”从来没有打算最终出现在生产代码中。 不过,由于这似乎是不可避免的,因此即使是 20 行概念验证代码也应该是清晰的,因为它们最终可能成为大型项目的基础之一。

我的方法是自上而下的。 我编写

while( obj = get_next_obj(data) ) {
  wibble(obj);
  fumble(obj);
  process( filter(obj) );
}

并稍后才开始编写所有这些功能。 (通常它们是内联并进入未命名的命名空间。有时它们被证明是单行代码,然后我可能会在以后消除它们。)

这样我也避免了必须评论算法:函数名称足以解释。

My rule of thumb is that anything longer than 20 LoC should be clean. IME every project stands on a few "just-a-proof-of-concept"s that were never intended to end up in production code. Since this seems inevitable though, even 20 lines of proof-of-concept code should be clear, because they might end up being one of the foundations of a big project.

My approach is top-down. I write

while( obj = get_next_obj(data) ) {
  wibble(obj);
  fumble(obj);
  process( filter(obj) );
}

and only start to write all these functions later. (Usually they are inline and go into the unnamed namespace. Sometimes they turn out to be one-liners and then I might eliminate them later.)

This way I also avoid to have to comment the algorithms: The function names are explanation enough.

琉璃繁缕 2024-08-03 23:29:09

您几乎已经确定了问题所在。 没有足够的计划。
花一些时间分析您要开发的解决方案,将其分解为功能块,确定如何最好地实现它们,并尝试分离应用程序的各个层(UI、业务逻辑、数据访问层等) )。

尽早从 OOP 角度进行思考并重构。 这比一切都建成之后再做要便宜得多。

You pretty much identified the issue. Not having enough planning.
Spend some time analyzing the solution you're going to develop, break it down into pieces of functionality, identify how it would be best to implement them and try to separate the layers of the application (UI, business logic, data access layer, etc).

Think in terms of OOP and refactor as early as it makes sense. It's a lot cheaper than doing it after everything is built.

玩物 2024-08-03 23:29:09

尽量少地编写 main 函数,其中几乎不包含任何内容。 在大多数 GUI 程序、sdl 游戏程序、open gl 或任何具有任何类型用户界面的程序中,主要功能应该只不过是一个事件吃循环。 必须如此,否则总会有很长一段时间计算机似乎没有响应,并且操作系统认为可能会关闭它,因为它没有响应消息。

一旦获得主循环,请快速锁定它,仅针对错误修复进行修改,而不是新功能。 这可能最终会将问题转移到另一个函数,但无论如何,在基于事件的应用程序中拥有一个整体函数是相当困难的。 您总是需要一百万个小事件处理程序。

也许你有一个单一的类。 我已经这么做了。 处理它的主要方法是尝试保留依赖关系的心理或物理地图,并注意哪里有……比方说,一组函数不明确依赖于任何共享状态或变量的穿孔、裂缝。类中的其他函数。 在那里,您可以将该函数集群分离到一个新类中。 如果它真的是一个巨大的类,并且真的很混乱,我会称之为代码味道。 考虑重新设计这样一个东西,使其变得不那么庞大和相互依赖。

您可以做的另一件事是,在编码时,请注意,当一个函数增长到不再适合单个屏幕的大小时,它可能太大了,此时开始考虑如何将其分解为多个较小的功能。

Write the main function minimally, with almost nothing in it. In most gui programs, sdl games programs, open gl, or anything with any kind of user interface at all, the main function should be nothing more than an event eating loop. It has to be, or there will always be long stretches of time where the computer seems unresponsive, and the operating system thinks considers maybe shutting it down because it's not responding to messages.

Once you get your main loop, quickly lock that down, only to be modified for bug fixes, not new functionality. This may just end up displacing the problem to another function, but having a monilithic function is rather difficult to do in an event based application anyway. You'll always need a million little event handlers.

Maybe you have a monolithic class. I've done that. Mainly the way to deal with it is to try and keep a mental or physical map of dependencies, and note where there's ... let's say, perforations, fissures where a group of functions doesn't explicitly depend on any shared state or variables with other functions in the class. There you can spin that cluster of functions off into a new class. If it's really a huge class, and really tangled up, I'd call that a code smell. Think about redesigning such a thing to be less huge and interdependant.

Another thing you can do is as you're coding, note that when a function grows to a size where it no longer fits on a single screen, it's probably too big, and at that point start thinking about how to break it down into multiple smaller functions.

橘寄 2024-08-03 23:29:09

你的方法不一定是坏的——早期的模块化设计可能最终会导致过度设计。

你确实需要重构——这是生活的事实。 问题是什么时候? 为时已晚,重构的任务太大,风险也太大。 为时过早,可能会过度设计。 而且,随着时间的推移,您将需要一次又一次地重构。 这只是软件自然生命周期的一部分。

诀窍是尽快重构,但不要太快。 而且经常,但不要太频繁。 多久以及多久一次? 这就是为什么它是一门艺术而不是一门科学:)

Your approach isn't necessarily bad -- earlier more modular design might end up as over-engineering.

You do need to refactor -- this is a fact of life. The question is when? Too late, and the refactoring is too big a task and too risk-prone. Too early, and it might be over-engineering. And, as time goes on, you will need to refactor again .. and again. This is just part of the natural life-cycle of software.

The trick is to refactor soon, but not too soon. And frequently, but not too frequently. How soon and how frequently? That's why it's a art and not a science :)

注定孤独终老 2024-08-03 23:29:09

如果您有好的工具来进行重构,那么重构就不那么可怕了。 我看到您将问题标记为“C++”,但任何语言都是如此。 获取一个可以轻松执行提取和重命名方法、提取变量等操作的 IDE,然后学习如何有效地使用该 IDE。 那么 Stefano Borini 提到的“小型增量重构”就不会那么令人畏惧了。

Refactoring is a lot less scary if you have good tools to do it. I see you tagged your question as "C++" but the same goes for any language. Get an IDE where extracting and renaming methods, extracting variables, etc. is easy to do, and then learn how to use that IDE effectively. Then the "small, incremental refactorings" that Stefano Borini mentions will be less daunting.

我不在是我 2024-08-03 23:29:08

是的,解决方案很简单,尽管需要时间来适应。
永远不要声称会有“稍后”,你坐下来进行重构。 相反,继续向代码(或测试)添加功能,并在此阶段执行小型增量重构。 “以后”基本上是“总是”,但隐藏在你每次实际上都在做新事情的阶段。

Yes, the solution is easy, although it takes time to get used to it.
Never claim there will be a "later", where you sit down and just do refactoring. Instead, continue adding functionality to your code (or tests) and during this phase perform small, incremental refactorings. The "later" will basically be "always", but hidden in the phase where you are actually doing something new every time.

注定孤独终老 2024-08-03 23:29:08

“首先我们养成习惯,然后习惯养成我们。”

这似乎适用于好习惯和坏习惯。 听起来好像有一个坏人抓住了你。

练习预先更加模块化,直到它“就是我做事的方式”。

"First we make our habits, then they make us."

This seems to apply for both good and bad habits. Sounds like a bad one has taken hold of you.

Practice being more modular up front until it's "just the way I do things."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文