当我提高设计的干燥度时,我经常发现自己拥抱“现在比没有更好”。通常,我发现我需要在其他知识体系的背景下,对一种知识建立对一个权威位置的理解。因此,我倾向于将系统设计为“现在”。
相反,尽管有一定的机会我不需要它,但这种做法仍使我提前建立了。
这两种模式如何相符?
您使用什么方法来确保它们表现良好?
您如何一起教他们又不引起混乱?
当我提高设计的干燥度时,我经常发现自己拥抱“现在比没有更好”。通常,我发现我需要在其他知识体系的背景下,对一种知识建立对一个权威位置的理解。因此,我倾向于将系统设计为“现在”。
相反,尽管有一定的机会我不需要它,但这种做法仍使我提前建立了。
这两种模式如何相符?
您使用什么方法来确保它们表现良好?
您如何一起教他们又不引起混乱?
Answers:
我也尝试着想得更远,但通常不在代码中。我集思广益并记笔记,希望组织得井井有条,以便我可以再次参考。
在代码方面,我更倾向于“您将不需要它”,但是在设计方面,“现在总比没有好”。
在开始构建新系统时,很想立即构建所有内容,但它也会削弱您的动力和士气。我倾向于考虑整体设计,并试图通过它来画一条直线-提出一个端到端的骨架架构,并首先应用合理的设计原理来构建它,以便以后我可以对其进行改进和重构以实现新功能。
建立可以工作的最简单的系统端到端表示;首先,然后您需要反思。这往往有助于使所有那些模糊的“假设”问题明确化,并帮助您确定下一步需要做什么。
YAGNI意味着事情在需要完成时而不是之前完成。这并不意味着他们永远不会完成,除非永远不需要它们。这意味着您只做能给客户带来直接业务价值的事情。立即的商业价值意味着对每个客户和每个项目都有主观性。
无论哪种情况,使用YAGNI 都不会丢失任何东西。
在另一种情况下,您会浪费时间来编写永不使用的代码,为永不使用的代码编写测试,为永不使用的代码编写文档以及对永不使用的代码进行维护,这使人们不知所措,并且一旦被使用,就会产生恶作剧。
例
如果我正在研究原型/概念证明或应用程序的1.0版本,那么我不需要进行设计就可以扩展到Facebook级别。地狱,直到我开始发现自己拥有这种流量,我才需要将设计扩展到Facebook的水平。
您认为扎克伯格设计的第一个Facebook版本可以扩展到5亿用户吗?不,他设计并制造了它,只是想要它要做而已。如果他从第一天开始就为5亿用户设计出瀑布,那么Facebook可能永远不会发布。
做事的实际方法是他的做法。他开始使用PHP和MySQL,然后根据业务价值进行了重新设计和重写,将其扩展到数百万个用户具有巨大的业务价值,但在第0天就没有。在第0天,只是启动某项东西便具有了巨大的业务价值。
他计划重新设计和重写。这与计划厨房水槽的想法不同,从不实际开发或交付任何有用的有用东西。
生命周期规划代码库并进行重写是敏捷的,并且是面向未来的。试图提出一些不确定的“灵活”目标只是每次都以失败告终。您无需任何浪费就可以进行业务价值的设计,而不是如愿地梦想着永远不会使用的功能。
我认为他们根本不会一起玩。我认为您要么倾斜,要么倾斜。我倾向于YAGNI。
但是,就其价值而言,我不同意第二点建议,即“现在总比没有好”。如果一项要求很重要,那么必须完成。因此,“永远”是不可能的。如果这不重要,那么“现在”就不会更好-“从不”会更好。
只是我的两分钱。
如果“从不”表示“不是现在”,则说明您的设计存在缺陷。
您做出的本地决策应该对系统的其余部分透明。
例如,如果您有一个component CookieSource
,它需要根据您的一些输入参数CookieFactory
将其将CookieRecipes
其转换Cookies
为,则CookieSource
不必,因此也不必取决于如何CookieFactory
实现和CookieRecipes
表示。
如果CookieFactory
实际上是a Bakery
,则可以Recipe
根据需要考虑任何因素Pastry
。并且除非您需要该功能,否则无需实现它。而且,世界上没有理由不能在以后添加它,除非它们之间CookieSource
和使用的服务之间没有明确的抽象障碍。
在构建软件时,请根据需要添加功能,并尽量不要将自己锁定在做出的任何决定中。而是将决策锁定为适当的抽象。
我发现的最简单的解决方案是在预先编写代码时期待更改。当我将一些布尔值传递给函数时,通常会尽快将其更改为一个标志/枚举,这样它a)更具可读性,b)易于扩展。类似地,如果我注意到我在需要闻的地方传递了一堆参数,我通常会创建一个特殊的结构。希望是YAGNI,但如果您在某个时候这样做,它不会立即破坏所有用户,并且“艰巨的工作”已经完成。通常,您也可以只添加一些注释,例如/ *将来的添加内容放在此处* /左右,因此很明显尚未实现,但这里是添加它的地方。这通常最有帮助,因为我后来发现接口重构最耗时。
在设计时会考虑将来的扩展,但是在需要它们之前不要实现这些扩展。
想到的示例是Netflix首次启动时,每个帐户只能有一个队列。他们后来入侵了对多个队列的支持。因为从一开始就不是这样设计的,所以维护变得越来越困难,因此他们决定停止使用该功能。在客户骚动之后,他们忍住了子弹,并进行了重新设计以正确集成多个队列。
如果一开始的人允许他们以后可能想要多个队列,那么他们本可以为自己节省很多长期的痛苦,而只需要很少的短期工作。他们不必立即真正实现多个队列,只需确保他们曾经这样做就不需要大量的重写或无法维护的黑客。
从表面上看,这似乎需要像算命先生一样的能力来预测未来的需求,但是在实践中,当一个好的程序员注意到他正在对某些东西或数据库表进行硬编码时,这样的事情往往会浮出水面。正在收集很多仅含糊的相关列。