如何(或者,如果)避免类之间的交叉依赖
本文关键字:之间 依赖 或者 如果 如何 | 更新日期: 2023-09-27 17:54:00
我正在做一个练习,涉及实现一个简单的纸牌游戏(类似于拉米)。
所以,我有一个Card
类,它有suit
和rank
成员。我有一个继承自List<Card>
的Cards
类。
我正在编写代码来检查获胜条件,这包括查找玩家的手牌是否包含运行(9H, 10H, JH, QH)或匹配集(2H, 2D, 2C)。
所以,我在Cards
类上实现代码,以查找集合中包含的任何运行或集。查找运行的第一步(至少是我实现它的方式)是先按花色排序,然后按排名排序。然后,找到匹配集的第一步是按秩排序,然后按花色排序(我猜按花色排序并不是严格需要的,但我这样做是为了确保牌总是按照可预测的顺序排序)。
所以,我创建了一个类CardComparerSuitRank : IComparer<Card>
和另一个类CardComparerRankSuit : IComparer<Card>
。然后,如果调用myCardsInstance.FindLargestSet()
,该方法所做的第一件事就是创建一个称为cardsToSearch
的Cards
实例的浅拷贝,并调用cardsToSearch.Sort(CardComparerRankSuit.Default)
,然后它遍历cardsToSearch
并记录最大的匹配集。
当我在做这件事的时候,我意识到这是在为我的Cards
类创建一个对CardComparerRankSuit
的隐式依赖。为了提供所有公开的功能,Cards
依赖于比较器类。这看起来很糟糕,因为在我看来,一个类应该封装它所公开的所有功能(或者至少,如果它依赖于另一个类,那么依赖应该是显式的,就像通过继承一样)。
那么,我的问题是,我使用什么模式来避免这种情况?我敢打赌,一定有一种方法可以编写这个类,使这个功能被完全封装,但这似乎会导致编写一个庞大的、难以阅读的类定义。或者,我可以通过类/接口继承的某种组合,在多个源文件之间更合理地分配功能吗?或者我应该放松一下,坚持我上面描述的模式,不要担心那么多?
这绝对是奇怪的,你是从List<Card>
派生。在这种情况下,组合(保存List<Card>
的实例)比继承更可取。
稍微解释一下,你的"Cards"类不是List<Card>
的"类型"。它"有"一个卡片列表。"有型"关系是继承,"有型"关系是复合。
就你对比较器类的依赖而言,这对我来说完全有意义。依赖关系几乎从来不会通过继承来解决,而是通过聚合/组合来解决。您可以做的唯一更改是让比较器从一些"ComaprisonStrategy"接口派生,这样您就可以将模拟注入"Cards"类中进行单元测试。
澄清一下,如果相反,比较器类依赖于"Cards",这将是一个问题,因为比较器不应该关心源来自何处。
如果我能澄清什么,请告诉我!
实现CardComparerSuitRank
和CardComparerRankSuit
作为私有类嵌套在Cards
类中。您没有公开排序背后的机制,任何依赖项都隐藏在Cards
类中。
整个类的结构实际上是不同的。您确实希望您的类尽可能地表示真实世界,特别是当您实际上试图用真实世界的对象表示真实场景时。
在现实世界中,你有一个纸牌游戏,玩家手中都有一些牌。每个玩家看着自己的手牌,决定这是赢还是输。如果他赢了,他会在适当的时候说出来,然后游戏就结束了。
所以对于一款软件游戏,你需要一个能够控制一切的游戏对象。你需要将玩家对象添加到游戏的玩家数组中。每个玩家都有一个手牌对象,其中包含一个卡牌对象数组。
Game对象创建了一些Player对象,并传递给每个玩家一个Hand对象。
之后,它遍历每个Player对象并询问他们是否有获胜的手牌,这是由每个Player对象调用使用System的Hand类中的一些方法/属性完成的。