Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 你的课程应该有多灵活?_Oop_Design Patterns_Architecture - Fatal编程技术网

Oop 你的课程应该有多灵活?

Oop 你的课程应该有多灵活?,oop,design-patterns,architecture,Oop,Design Patterns,Architecture,我一直在想,在编写代码之前,我是想得太多还是太少。如果我不确定将来需要考虑哪些可能的需求变化,这对我来说尤其如此。我不知道我的类应该有多灵活或抽象。我来举个简单的例子 你想写一个程序,在电脑上玩21点游戏,而你就是那种喜欢实验的人。您开始为组编写代码,但随后您意识到21点可以有1、2、4或任意数量的组。你解释了这一点,但随后你意识到,可能牌组会被改变,没有任何价值10的牌。然后,您决定甲板应该是完全多功能的,以允许任何数量的西装或军衔。然后,您决定牌组的规则应该能够从标准套牌数乘以唯一等级更改为

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

你想写一个程序,在电脑上玩21点游戏,而你就是那种喜欢实验的人。您开始为组编写代码,但随后您意识到21点可以有1、2、4或任意数量的组。你解释了这一点,但随后你意识到,可能牌组会被改变,没有任何价值10的牌。然后,您决定甲板应该是完全多功能的,以允许任何数量的西装或军衔。然后,您决定牌组的规则应该能够从标准套牌数乘以唯一等级更改为等于牌组中的牌总数。。。你可以看到我要去哪里


我的问题是,对于一个班级应该有多灵活,有什么指导方针吗

我尝试遵循雅格尼的敏捷原则你不会需要它的

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


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

支持简约主义和封装,避免不需要的功能

当然,根据需要进行设计是很好的,但是将设计与您不使用的东西(或者将来可能使用的东西)混为一谈应该被最小化。考虑和实施你确信你需要的是很好的。


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

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

查看大卫·帕纳斯(David Parnas)在1972年发表的伟大论文


一般来说,您应该尝试确定可以在隐藏有用功能和复杂性的非常简单的界面后面推动的责任领域。您应该努力将您认为最有可能改变的领域(即预测变化)中的“什么”与“如何”区分开来.

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

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

接口或继承将有所帮助,因为您可以轻松地使用
NoTenDeck
SpadeOnlyDeck
交换
DeckRule
hardtowinkrule
不可能的windeckrule
。使用
decorator
或其他设计模式,如
composite
wi别忘了测试单元,它将帮助你重构代码

此外,有时您还需要一些类似于“破坏更改”的东西,在这些东西中,您需要拆除当前的体系结构和接口,以替换为另一种设计。有时需要,但大多数情况下不需要


您可以在stackoverflow上找到一些讨论。

关于灵活性的总体想法

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

关于21点问题

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

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

我对此的看法是

  • 你已经知道你的游戏将在未来发展,你将需要这样一个引擎。要回答问题的“提前思考”部分,这意味着您将从一个简单的标准回合结构、一个最小的规则引擎开始,并在实现积压工作中的每个功能时逐步添加到该结构中。你不应该做的是尝试预先预测引擎中的每一个细节。换句话说,您将使用
    “我不需要游戏中的这种规则/类型的钩子”
    ,而不是
    “我不需要规则引擎”
    ,因为您知道您无论如何都需要规则引擎
或者

  • 至少在一开始,这将是一个一次性的固定规则游戏。在这里,游戏系统需要更少的原始灵活性。专注于用例并尝试