为什么执行 YAGNI 如此困难?

发布于 2024-08-05 02:46:52 字数 1432 浏览 8 评论 0原文

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

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

发布评论

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

评论(15

瑾夏年华 2024-08-12 02:46:52

为某些东西而设计

……与设计某些东西完全不同

设计意味着您正在构建应用程序以供将来扩展,以防需要编写代码(这很好......这意味着您正在使您的软件可扩展且易于维护)。

设计一些东西意味着你现在正在写整个作品......无论你认为有人是否真的会使用它。这不一定是坏事,但可能会浪费大量时间。

小心你在做什么。

Designing FOR something

...is completely different than

Designing something.

Designing for something means you're architecting your application for future expansion in case the need arises to write the code (which is good...it means you're making your software extendable and easy to maintain).

Designing something means you're writing the whole piece now...whether you think anybody is actually going to use it or not. That isn't necessarily a bad thing, but it can be a huge waste of time.

Be careful about which one you're doing.

盗梦空间 2024-08-12 02:46:52

这与完美主义有一定关系。让我们让它变得完美,让我们为未来所有可能的情况做好准备。

在决定需要的机会时,保持务实和清醒是有帮助的:做出然后回答“是”或“否”。也许是不。

除非有明确的证据表明需要它(它已列入议程,是客户要求的)并且您认为最好在当前设计中考虑未来的功能,否则暂时将其保留。

This has something to do with perfectionism. let's make it perfect, let's make it ready for all possible future scenarios.

It helps to be pragmatic and sober when deciding on the chances it will be needed: make then answer either "Yes" or "No". Maybe is a no.

Unless there is a clear evidence it will be needed (it's on the agenda, it's been asked for by a customer) and you see it is better to account for that future functionality in your current design, leave it out for now.

萌逼全场 2024-08-12 02:46:52

只需使用 TDD 即可!

您很少会发现自己正在为不需要的功能编写测试......

Just use TDD !!!

rarely you wil find yourself writing a test for a feature that you don't need...

寄居人 2024-08-12 02:46:52

因为YAGNI是一个原则,而不是万能药
软件开发总是要平衡许多需求。重要的不是把一件事做对,而是不要做错很多事情。仅靠 YAGNII 救不了你。

从这个意义上说,YAGNI 是为了避免以下陷阱:

  • 当你需要编译器时,创建一个编译器 - 而不是一个自编译的编译器框架
    (我们的优势 - 解决一般问题 - 也是我们的弱点)
  • 不要低估实施工作。
  • 不要高估应用程序的生命周期和需求的稳定性

平衡相互竞争的需求是很困难的。但这就是为什么——正如麦康奈尔尖锐地指出的——软件开发就是工程。

因为其他原则也是人
其他原则 - 更基本的 IMO - 是最小惊喜原则复杂性封装:实体的公共接口/契约应该比它的实现更简单 - 否则,为了正确调用一个函数,我必须知道比我自己需要知道的更多的信息。有时,这意味着您的实施需要完成。

一个例子(也许不是一个很好的例子):

/// Estimates the time required to comlete the batch.
/// If the time cannot be estimated reliably, the return value is -1
/// \returns [double] estimated time in seconds
double EstimateDuration(Batch & batch);

是一份简单的合同。 OTOH,

/// Estimates the time required to comlete the batch.
/// If the time cannot be estimated reliably, the return value is -1.
/// This function does not support looping batches (right now, looping
/// batches only run under a servicve account with no UI, so it's not needed).
/// Also, when the moon is full, the return value is -1, but an estimate 
/// is found in batch.JeffsEstimate. This value is used only by Jeff's core 
/// build script which runs roughly once a month.
/// \returns [double] estimated time in seconds
double EstimateDuration(Batch & batch);

不是合同,它是对实施的描述。
(有人可能会争论这些问题是否是过于热心的 YAGNI 造成的,或者仅仅是糟糕的设计 - 但也许那是因为你完全是 YAGNI 设计的)

设计不会造成伤害
随着敏捷的出现,“设计阶段”的名声变得不好了。然而,比没有计划更糟糕的是,你的计划确实是灾难性的。最大的危险并不是真正糟糕的计划,而是试图预测每个问题和变更请求。亚格尼在这里的价值是无价的。


毕竟他们是资深
我不认识他们——他们的倾向可能是由于老派的瀑布灌输和对改变的恐惧。或者也许他们是资深人士,因为他们了解自己的工作 - 他们知道哪些部分是你现在应该做而不是以后再做的,以及哪些部分可以因为未来的不确定性而牺牲。

Because YAGNI is a principle, not a panacea
Software Development is always about balancing many requirements. It's not about getting one thing right, rather getting none of many wrong. YAGNII alone won't save your ass.

In that sense, YAGNI is there to avoid the following pitfalls:

  • When you need a compiler, create a compiler - not a self-compiling compiler framework
    (Our strength - solving the general problem - is also our weakness)
  • Don't underestimate implementation effort.
  • Don't overestimate lifetime of your application and stability of requirements

Balancing competing requirements is hard. But that's why - as McConnell poignantly stated - software development is engineering.

Because other principles are people, too
Other principles principle - more fundamental IMO - is the principle of least surprise and the encapsulation of complexity: the public interface / contract of an entity should be simpler than it's implementation - otherwise, to call a function correctly I would have to know more than I needed to do it myself. sometimes, that means your implementation needs to be complete.

One example (maybe not a very good one):

/// Estimates the time required to comlete the batch.
/// If the time cannot be estimated reliably, the return value is -1
/// \returns [double] estimated time in seconds
double EstimateDuration(Batch & batch);

is a simple contract. OTOH,

/// Estimates the time required to comlete the batch.
/// If the time cannot be estimated reliably, the return value is -1.
/// This function does not support looping batches (right now, looping
/// batches only run under a servicve account with no UI, so it's not needed).
/// Also, when the moon is full, the return value is -1, but an estimate 
/// is found in batch.JeffsEstimate. This value is used only by Jeff's core 
/// build script which runs roughly once a month.
/// \returns [double] estimated time in seconds
double EstimateDuration(Batch & batch);

Is not a contract, it's a description of the imlementation.
(One could argue if the problems are a result of overzealous YAGNI or simply bad design - but maybe that's because you YAGNI'd design altogether)

Design doesn't hurt
Will the advent of agile, the "design phase" got something of a bad name. However, to be worse than no planning at all, your plans must be catastrophic indeed. The biggest danger is not genuinely bad plans, but trying to anticipate every problem and change request. YAGNI is invaluable here.


They are senior, after all
I don't know them - Their tendency may be due to old-school waterfall indoctrination and fear of change. Or maybe they are seniors because they know their job - they've learnt what parts you rather do now than later, and what parts can be sacrificed to the uncertanities of the future.

末が日狂欢 2024-08-12 02:46:52

执行 YAGNI 非常困难,因为我认为我们大多数人都遇到了相反的问题,即找到一个过于复杂或脆弱的系统,无法重构来实现我们想要的功能,但如果稍微深思熟虑,就可以实现它。找到中间立场可能很困难。

一般来说,如果您发现自己在想,“它可能需要 [xyz]”,那么这应该明确地在您的代码中发挥作用。即使您不编写支持 xyz 的代码,那么您也应该以这样的方式进行编码:重构以添加 xyz 支持尽可能实用。然而,有时这可能意味着使某些东西比严格需要的更通用。知道沿着这条路径在哪里停止可能只有特定领域的信息加上经验才能告诉您。

It's so hard to enforce YAGNI because I think most of us have been bitten by the opposite problem, of finding a system that is too complex or brittle to refactor to do what we want, but which could have allowed for it with a little more forethought. Finding the middle ground can be tough.

Generally speaking, if you find yourself thinking, "it might need [xyz]", then that should explicitly play a part in what you code. Even if you don't code in support for xyz then you should be coding in such a way that refactoring to add xyz support is as practical as can be. Sometimes however that may mean making something more generic than it strictly needs to be. Knowing where to stop along that path is probably something that only domain specific information coupled with experience can tell you.

嘴硬脾气大 2024-08-12 02:46:52

“回归基础”和“简单即是好”是弹出来的几个短语,提醒我专注于手头的任务,并意识到为什么我要构建此功能或增强功能,而不是过度设计或计划一百万个可能不会发生的事情。在我工作的地方,我的名字经常被用来描述一些过度设计或过于复杂的东西,例如“你告诉我如何构建该页面”。我试图更多地控制这一点,因为有时它很有用,但不足以成为我的常见做法。

用非技术术语写出需求有时也会有所帮助。这让我知道最后必须显示什么,而不用担心更精细的细节,例如系统的用户不太可能阅读我的源代码并嘲笑我对我们使用的任何命名约定的使用。他们关心它是否有效,是否能满足他们的需要并希望它能做到。

另一个要问的问题是,“他们真的要求这样做吗?”并尽量减少对功能的假设。如果它不在列表中,则将其保留,但询问他们是否想要它。

"Back to basics" and "Simple is good" are a couple of phrases that pop up to remind me to just stay on the task at hand and realize why am I building this feature or enhancement and not get into overengineering or planning for a million things that probably won't happen. Where I work my name is often used as a way to describe something overengineered or overly complex,e.g. "You JBed how to build that page." I am attempting to keep this in check more as sometimes it is useful but not often enough for it to become my common practice.

Having a requirement written out in non-technical terms can sometimes help too. This lets me know what I have to show at the end and not worry about the finer details, e.g. the users of the system aren't likely to read over my source code and mock my use of whatever naming convention we use. They care that it works and does what they need and want it to do.

Another question to ask is, "Did they really ask for this?" and try to minimize assumptions one makes about functionality. If it isn't in the list, then leave it out, though ask if they want it.

她说她爱他 2024-08-12 02:46:52

如果您正在构建一个库/工具包/平台/框架,YAGNI 具有不同的含义。

您无法确定其他开发人员将如何使用您的工具,有时灵活地设计更有意义,以便您的产品可以用于更广泛的场景。向前兼容性也是一个重要的考虑因素。

YAGNI 仍然适用,但“它”往往处于元特征级别,而不是特征级别。

If you are building a library/toolkit/platform/framework, YAGNI takes on a different meaning.

You can't be sure how other developers are going to use your tool, and sometimes it makes a lot more sense to design with flexibility, so that your product can be used in a wider variety of scenarios. Forward compatibility is also a huge consideration.

YAGNI still applies, but the "it" tends to be at a meta-feature level, rather than a feature level.

绝不放开 2024-08-12 02:46:52

YAGNI 实际上更像是一个需要问的问题。作为高级开发人员,我们一直违反 YAGNI。这确实是一个“需要”的问题。你需要吗?定义“需要”。我见过使用 YAGNI 教条开发出的可怕的泥球。

并不是说我认为 YAGNI 没有用……总是值得问“我需要这个吗”。

YAGNI is really more of a question to ask. We, as senior developers, violate YAGNI all the time. It is really a question of "need". Do you need it? Define "need". I have seen awful balls of mud developed using the YAGNI dogma.

Not that I think YAGNI isn't useful... it is always worth asking "Do I need this".

怀里藏娇 2024-08-12 02:46:52

好吧,我昨天也遇到了同样的事情,并且和一位高级开发人员大吵了一架。我总是尝试以“如果有人调用这个怎么办,如果这改变了 tomm 等等怎么办?”来设计。而他则是另一个极端。 “让它快速工作!”

答案介于他的方法和我的方法之间。我们如何达到中间立场?试图做出一个“完美”的设计,如果将来必须改变某些东西,人们会欣赏或讨厌。

恕我直言,至少在设计模块时,答案可以归结为面向对象编程的基本原则,例如定义清晰的接口。
接口应符合客户的要求。模块的主接口不应该有任何“解决”任何问题的东西,除了需求中的内容。至少可以删除由于“如果情况发生变化怎么办,他们明天需要这个等”而添加的某种程度的“装饰”。

任何你打算放置的东西,因为你认为明天可能会被其他人使用等等,都必须争论几个小时!您应该有充分的理由为目前甚至没有名字的人添加“免费赠品”!

这个问题我还需要一个明确的答案。也许来自这里的一些架构师,他设计过大型应用程序并遇到过这种情况 100 次:)

Well, I ran into the same thing yesterday and had a big fight with one of the senior developers. I always try to design with "what if SOMEONE calls this, what if this changes tomm etc etc..?" and he is the other extreme. "Just make it work and FAST!"

The answer is somewhere in between his approach and mine. How do we come to the middle ground? Between trying to make a "perfect" design which people would appreciate or HATE if they have to change something in future.

IMHO, the answer, at least while designing a module, boils down to basic principles of Object Oriented Programming, things like defining clear interfaces.
Interfaces should match with the requirement from customer. The main interfaces for module should not have anything which "solves" anything except whats there in the requirement. At-least some level of "frills" added due to "what if this changes, they need this tomorrow etc" can be removed.

Anything that you are planning to put because you think this MIGHT be used tomorrow by someone else etc has to be debated for hours! You should have good reasons for adding a "freebie" for SOMEONE who currently doesn't even have a name!

I still need a definitive answer for this question. Maybe from some architect here who has designed big applications and faced this situation 100 times :)

戴着白色围巾的女孩 2024-08-12 02:46:52

最好以一种使未来功能更易于实现的方式设计应用程序,但在需要之前不要实际实现这些功能。如何去做这件事完全取决于您正在从事的项目。

It is good to design your applications in a way that will make future features easier to implement -- but don't actually implement the features until you need to. How to go about doing this is entirely dependent on the project you're working on.

我喜欢麦丽素 2024-08-12 02:46:52

我发现同行评审和同行编程对此有帮助。另一双质疑你推理的眼睛会很快识别出你认为你需要但实际上并不需要的东西。

I find peer reviews and peer programming help with this. Another set of eyes questioning your reasoning will quickly identify things you think you need, but don't really.

孤凫 2024-08-12 02:46:52

我们公司有一条经验法则:当我们讨论设计新功能时,要回答的第一个问题是“谁真正想要这个?”如果客户支持它,那么我们会尝试了解他真正想要什么,以及是否有其他方法可以解决他的问题(而不是添加新功能)。如果团队成员要求此新功能,他应该有充分的理由为此。性能问题和营销问题就是其中之一,在向代码库添加一些新功能之前,我们再次尝试充分理解请求并讨论所有可能的替代方案。

We have a rule of thumb in our company : When we are discussing designing a new feature the first question to be answered is "Who really want this?" if a customer is behind it then we try to understand what he really wants and if there are another ways to solve his problem (rather than adding a new feature).If a member of team is asking for this new feature he should have good reasons for that. Performance issues and marketing concerns are among them and again we try to fully understand the request and discuss all possible alternatives before we add some new features to our code base.

若言繁花未落 2024-08-12 02:46:52

提醒自己你正在努力实现什么,不要做更多。您可以通过

  • 清晰编写的用户故事/需求来做到这一点。如果你的作品的“验收标准”被明确列出,就更容易判断某些东西是好还是坏。
  • 期望你快速完成事情的人(也许是你自己)。这迫使你确保自己不会偏离轨道。
  • TDD
  • 结对编程,或类似的
  • 每日站立会议(或更频繁),以确保您不会陷入困境

Remind yourself what you are trying to implement, and don't do more. You can do this with

  • clearly written user stories/requirements. If the "acceptance criteria" for your work is clearly outlined, it's easier to judge whether something is in or out.
  • someone (maybe yourself) who expects you to complete things rapidly. This forces you to make sure you're not going off track.
  • TDD
  • pair programming, or something close to it
  • daily stand-ups (or more frequent), to make sure you're not going off into the weeds
猫七 2024-08-12 02:46:52

如果您遵循敏捷,那么您可以处理重要的事情,直到处理您不需要的事情为止。当你接触到 YAGNI 的东西时,你应该已经有了一个差不多的成品。然后,企业就会告诉你停止开发东西。

If you are following Agile then you can work on the important stuff until you get to the stuff you aren't going to need. By the time you get to the YAGNI stuff you should have a pretty much finished product. It would then be up to the business to tell you to stop developing stuff.

爱的那么颓废 2024-08-12 02:46:52

YAGNI 通常是事后诸葛亮。只要确保当“YAGNI”变得明显时,您足够敏捷,可以删除“I”。

YAGNI is often a hindsight thing. Just make sure you're agile enough to remove the "I" when "YAGNI" becomes obvious.

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