4

我已经按照 Scrum、TDD、领域驱动设计和 Bob 叔叔的食谱工作了一年。但我对我们是否应用了各种原则有一些疑问,主要是在阅读 Martin 的系列中的“Java 应用程序架构”(从现在的 JAA)时. 如果我错了,请纠正我!(希望我是)问题从 TDD 和 Scrum 开始,指出一旦需求出现,我们应该改进系统来实现需求,避免前期设计。这使我的工作使所有可扩展点保持打开状态,(ab)始终使用各种可扩展性模式。这确实有一个“阴暗面”:增加了整个系统的复杂性。我事先不知道我的代码的某个部分是否需要进一步发展。

但是,正如在各处正确说明的那样(在 JAA 上确实经常如此),您应该仅在需要时添加复杂性。这个恕我直言的结论是,应该进行体面的前期分析......与其他食谱相冲突......

因此循环.... aaargh 我讨厌循环依赖!

在“确认”一个特性之后,我们是否应该重构事物以降低复杂性?我们是否应该使用允许的最简单的方法,并且仅在需要时扩展它?例如,当您不需要它们时,不要构建超级解耦的东西吗?

(欢迎任何改进问题风格和内容的建议,我是stackoverflow的新手)

4

5 回答 5

8

在“确认”一个特性之后,我们是否应该重构事物以降低复杂性?我们是否应该使用允许的最简单的方法,并且仅在需要时扩展它?例如,当您不需要它们时,不要构建超级解耦的东西吗?

的。虽然这是相当主观的,但我不喜欢可以灵活地改变每一个要改变的东西的系统,而你不会利用所有这些灵活性。不过,您的说法是自相矛盾的:测试驱动开发教会我“做最简单的可能可行的事情”。

如果需要更多功能,您可以添加测试,然后重构和扩展代码以确保它执行您希望它执行的操作。因为您已经进行了测试,所以您可以放心,您不会破坏当前存在的代码。

简而言之:不要因为可以而建立灵活性。您应该建立灵活性,因为情况要求您这样做。我坚信“按需”重构会使项目的构建时间比内置(未使用的)灵活性更短。在测试到位后,“按需”重构应该不会花费太长时间。

更短:保持简单,愚蠢。;)

于 2012-08-30T08:16:38.703 回答
4

我相信在使事情变得简单和对系统的一些深入的体系结构理解之间存在平衡。

我试图将短期计划与长期计划分开。在短期规划中,我认为只有几步之遥,如果此功能可能会在下一次迭代中扩展/修改/更新,那么我将尝试为此做好准备。但如果我没有预见到任何扩展,我将遵循 KISS 原则。

在长期规划中,我认为至少提前半年。什么是互动,什么是可能的路线图?这给了我一些基本的想法,让我知道我应该在哪里让事情变得更高级一些。

恕我直言,应该在计划和完成短期目标之间做出明智的决定。

于 2012-08-30T08:23:14.277 回答
2

我怀疑有经验的设计师会带着直觉来进行。做出了“明显的”架构决策,分层,关注点分离设计决策有点“退出”。诀窍是避免分析瘫痪和过度设计。

随着粒度的增加,随着我们越来越接近代码,“你不需要它”的口号变得更加重要——它很容易被美丽的灵活性所束缚。但是你可以通过一些简单的方法来启用future flex。例如,用(在 Java 中)接口表示组件之间的关系。您可能不会选择完全成熟的抽象工厂模式,但如果消费者被编码为一个接口,那么很容易引入一个。同样,不要在代码周围散布字符串文字,而是将它们收集在一个地方,可以大大简化未来的国际化或动态配置,即使现在您不需要外部化字符串。

我看到的真正优秀的设计师似乎玩它就像玩国际象棋或围棋游戏,他们预测未来的动作,但当然在他们需要之前不会播放响应。(围棋术语aji-keshi可能值得考虑。)

哈这很有趣:我查阅了 aji-keshi 参考来解释这个术语,却发现作者已经将这个术语应用到系统设计中来解决这个问题!

于 2012-08-30T08:40:13.397 回答
1

毫无疑问,您应该首先添加做最简单的事情的代码 - 但您添加的代码应该遵守SOLID原则。

不要仅仅通过推测未来可能发生的变化来引入复杂性(例如设计模式、框架等)。

您正在解决的问题的基本复杂性无法改变。这需要预先思考、头脑风暴,但意外的复杂性会随着猜测而增加。

定期的同行代码审查会有所帮助。如果您的同行可以阅读和理解代码而不会引起注意 - 那么我认为应该没问题..

于 2012-08-30T15:28:35.570 回答
1

这使我的工作使所有可扩展点保持打开状态,(ab)始终使用各种可扩展性模式。这确实有一个“阴暗面”:增加了整个系统的复杂性。我事先不知道我的代码的某个部分是否需要进一步发展。

我们是否应该使用允许的最简单的方法,并且仅在需要时扩展它?

我认为至少可以通过调整您对“简单性”和“复杂性”的定义来解决这个难题。

JAA“秘诀”、 SOLID原则等都是管理设计中耦合内聚的捷径。如果您将设计的“简单性”定义为实现最大内聚和最小耦合的程度,那么您可以说这些原则和模式旨在使您的设计保持简单

因此,根据该定义,您所说的“可扩展点”实际上是保持设计简单的结果,因此不会增加复杂性。此外,它们是否会在未来被用于扩展的目的没有抓住重点,因为简单设计的目的是为了方便未来的变化

短语“做最简单的事情可能会起作用”,更多地指的是构建什么的选择,而不是代码的设计。例如,如果您需要显示 HTML 页面,请构建 HTML 页面,而不是 Web 应用程序。

因此,如果您在维护设计的方式上遵循上面对简单性的定义,并且只构建最少的代码来解决任何给定的问题,那么您的代码库将会更小,您的设计也不那么复杂,并且您的应用程序将邀请未来添加功能所需的更改。

最后一点:注意你的测试对你的设计有什么看法。耦合和内聚问题通常表现为笨重的测试夹具。当您看到这一点时,这表明您已经跳过了一些必要的重构步骤。

于 2012-09-04T12:48:34.303 回答