8

在编写代码之前,我一直想知道我是否提前考虑太多或太少。如果我不确定将来需要考虑哪些可能的需求变化,这对我来说尤其如此。我不知道我应该使我的课程多么灵活或抽象。我将举一个简单的例子。

您想编写一个与计算机玩二十一点的程序,并且您是那种喜欢尝试的人。您开始为牌组编写代码,但随后您意识到二十一点可能有 1、2、4 或任意数量的牌组。您对此进行了解释,但随后您意识到可能会改变套牌并且没有任何价值 10 的牌。然后你决定套牌应该是完全通用的,以允许任何数量的套装或等级。然后你决定套牌的规则应该能够从标准花色数乘以独特等级来改变,以等于套牌中的牌总数......你可以看到我在这里的去向。

我的问题是,对于课程的灵活性是否有任何指导方针?

4

6 回答 6

5

Check out the great paper "On the Criteria to be Used in Decomposing Systems into Modules" by David Parnas, from back in 1972.

Generally speaking, you should try to identify areas of responsibility that can be pushed behind a very simple interface that hides useful functionality and complexity. You should strive to separate the what from the how in areas you feel are most likely to change (i.e. predicting variation).

于 2013-09-26T21:08:29.580 回答
5

喜欢极简主义和封装,避免你不需要的功能。

根据需要进行设计当然是好的,但是应该尽量减少将你不使用的东西——或者将来可能使用的东西——弄得杂乱无章的设计。考虑并实施您确定需要的东西是很好的。

当您理解并指定一个“未来问题”(特别是在未来的某个时间点)时,您通常会以不同于今天的解决方案来解决它。

于 2013-09-26T20:53:12.720 回答
2

灵活性确实是应用程序/系统可维护的要求。通常我发现遵循 SOLID 设计原则、TDD 和无状态业务逻辑的设计更易于维护。

在所有 SOLID 原则中,我发现 [S]RP 是使应用程序可维护的规则。在 [S]RP 之后,您的系统将被分解成更小的部分,并带有可替换的类。说它可以分解为Deck, DeckRule,HitAction等。

接口或继承会有所帮助,因为您可以轻松地DeckNoTenDeck或交换您的SpadeOnlyDeck。你可以交换DeckRuletoHardToWinDeckRuleImpossibleWinDeckRule. 使用decorator或其他设计模式,例如也composite将有助于使您的系统灵活。不要忘记测试单元,它将帮助您重构代码。

有时您还需要一些类似Breaking Change的东西,您需要拆除当前的架构和接口,以便用另一种设计替换。有时需要,但大多数情况下不需要。

您可以在 stackoverflow answer for DI vs Singleton 找到几个讨论,而几乎没有关于 state 或 stateless 的讨论。

于 2013-09-27T02:41:55.803 回答
1

关于灵活性的总体思路

从您对问题的描述来看,我认为您的课程不应该像“将游戏规则的每个新方面都放在同一个课程中”那样灵活。一个职责太多的类是脆弱的,难以维护,因此也很难改变——具有讽刺意味的是,将一个类视为灵活的,最终会使它变得僵化!不要把所有的鸡蛋都放在一个篮子里。单独关注意味着单独的类。你的整体设计应该是灵活的,而不是你的类。

关于二十一点问题

纸牌游戏,尤其是复杂和/或不断发展的纸牌游戏,通常是最奇特的动物,因此在尝试提高设计技能时可能不是一个很好的标准示例。

如果你想要真正的模块化,你可能需要一个可插入的规则引擎,它允许插件在游戏的不同阶段挂钩,让你可以访问相关资源来改变任何东西,从分数到事件顺序,甚至是其他规则.

我对此的看法是

  • 您已经知道您的游戏将在未来发展,您将需要这样的引擎。要回答您问题的“超前思考”部分,这意味着您将从一个简单的标准轮次结构、一个最小规则引擎开始,并在您实现待办事项中的每个功能时逐步添加。您不应该做的超前思考是尝试预先预测引擎中的每一个小细节。换句话说,您将使用YAGNI"I ain't gonna need this rule/type of hook into the game"而不是"I ain't gonna need a rules engine"因为您知道无论如何您都必须拥有一个。

或者,

  • 至少一开始,这将是一个一次性的固定规则游戏。在这里,您将需要较少的游戏系统原始灵活性。专注于用例,并尝试用最简单的技术解决方案使验收测试通过。一次迈出一小步。首先使用简单的规则为 1 个套牌实施可行的解决方案,然后扩展到更复杂的领域。希望这将引导您进入一个严肃的、精心设计的系统,该系统可能涉及也可能不涉及某种规则引擎。

您可能还想查看https://gamedev.stackexchange.com/以了解特定于游戏的设计指南。

于 2013-09-27T10:35:49.907 回答
1

我尝试遵循 YAGNI 的敏捷原则!- 你不需要它。

提出所有这些可能的未来要求是不值得的。有无数种可能的未来需求。你不能解释所有这些。只需做你需要做的事情来满足你已有的要求。

如果将来你有新的要求,那么就改变系统。(你确实有很好的测试来确保你在重构过程中不会破坏任何东西,对吧?)

于 2013-09-26T20:52:25.337 回答
0

在编写代码时,我倾向于寻找以后可能会明显添加的东西。“不过,显然可能是一个需要定义的词。:-) 这意味着你确定会在未来的版本中出现。除此之外,我尽量不担心。

于 2013-09-26T20:54:38.457 回答