【问题标题】:How flexible should you make your classes?你的课程应该有多灵活?
【发布时间】:2013-10-03 00:24:41
【问题描述】:

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

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

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

【问题讨论】:

    标签: oop design-patterns architecture


    【解决方案1】:

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

    根据需要进行设计当然是好事,但应尽量减少使用您不使用或可能可能在未来使用的东西的混乱设计。考虑并实施您确定需要的东西是很好的。

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

    【讨论】:

      【解决方案2】:

      查看 David Parnas 于 1972 撰写的出色论文“On the Criteria to be Used in Decomposing Systems into Modules”。

      一般来说,您应该尝试确定职责范围,这些职责可以被推到一个隐藏有用功能和复杂性的非常简单的界面后面。在您认为最有可能发生变化的领域(即预测变化)中,您应该努力将内容与方式分开

      【讨论】:

        【解决方案3】:

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

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

        接口或继承会有所帮助,因为您可以轻松地将DeckNoTenDeckSpadeOnlyDeck 交换。您可以将DeckRule 交换为HardToWinDeckRuleImpossibleWinDeckRule。使用decoratorcomposite 等其他设计模式也有助于使您的系统更加灵活。不要忘记测试单元,它将帮助您重构代码。

        有时您还需要像Breaking Change 这样的东西,您需要在其中拆除当前的架构和接口以用另一种设计替换。有时需要,但大多数情况下不需要。

        您可以在 stackoverflow answer for DI vs Singleton and little about state or stateless 找到一些讨论。

        【讨论】:

          【解决方案4】:

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

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

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

          【讨论】:

            【解决方案5】:

            关于灵活性的总体思路

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

            关于二十一点问题

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

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

            我的看法是

            • 您已经知道您的游戏将在未来发展,您将需要这样的引擎。要回答您问题的“超前思考”部分,这意味着您将从一个简单的标准轮次结构、一个最小规则引擎开始,并在您实现待办事项中的每个功能时逐步添加。您不应该做的超前思考是尝试预先预测引擎中的每一个小细节。换句话说,您将使用 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/ 了解游戏特定的设计指南。

            【讨论】:

              【解决方案6】:

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

              【讨论】:

                猜你喜欢
                • 2010-11-27
                • 1970-01-01
                • 1970-01-01
                • 2011-04-12
                • 2011-07-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多