我正在尝试将扑克游戏转换为正确的OOP模型 基础知识:
class Hand
{
Card cards[];
}
class Game
{
Hand hands[];
}
我从文本文件中获取游戏和手牌。我解析了几次文本文件,原因如下:
由于原因1,我需要Hand类中的一些属性(a1,b1)。由于原因2,我需要一些其他属性(a2,b2)。我认为肮脏的方式是:
class Hand
{
Card cards[];
Int a1,b1;
Int a2,b2;
}
我的意思是大多数时候某些属性都没用。 所以,为了更清洁,我们可以这样做:
class Hand
{
Card cards[];
}
class HandForReason1 extends Hand
{
Int a1,b1;
}
但我觉得要用锤子......
我的问题是:有中间方式吗?或锤子解决方案是好的? (在这种情况下,什么是正确的语义?)
PS:欢迎设计模式:-)
PS2:策略模式是锤子,不是吗?
*编辑 * 这是一个应用程序:
// Parse the file, read game infos (reason 1)
// Hand.a2 is not needed here !
class Parser_Infos
{
Game game;
function Parse()
{
game.hands[0].a1 = ...
}
}
// Later, parse the file and get some statistics (reason 2)
// Hand.a1 is not needed here !
class Parser_Stats
{
Game game;
function Parse()
{
game.hand[0].a2 = ...
}
}
答案 0 :(得分:0)
使用一系列责任来识别扑克牌就是我要做的。由于每只手都有自己的特点,所以你不能只握手。
像
这样的东西abstract class Hand {
protected Hand next;
abstract protected boolean recognizeImpl(Card cards[]);
public Hand setNext(Hand next) {
this.next = next;
return next;
}
public boolean Hand recognize(Card cards[]) {
boolean result = ;
if (recognizeImpl(cards)) {
return this;
} else if (next != null) {
return next.recognize(cards);
} else {
return null;
}
}
}
然后进行实施
class FullHouse extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
class Triplet extends Hand {
protected boolean recognizeImpl(Card cards[]) {
//...
}
}
然后建立你的链
// chain start with "best" hand first, we want the best hand
// to be treated first, least hand last
Hand handChain = new FullHouse();
handChain
.setNext(new Triplet())
//.setNext(...) /* chain method */
;
//...
Hand bestHand = handChain.recognize(cards);
if (bestHand != null) {
// The given cards correspond best to bestHand
}
此外,每只手都有自己的类,你可以初始化然后保持并计算非常具体的东西。但是既然你应该尽可能多地操纵Hand
课程(尽可能多地保留OO),你应该避免将手伸向特定的手课。
** 更新 **
好吧,为了回答你的原始问题( sig ),班级Hand
用于操纵和处理“手”。如果你需要计算其他统计数据或其他需求,包装你的Hand
类可能不是一个好主意,因为你最终会得到一个复合类,这是不可取的(为了可维护性和OOP范例)。 / p>
原因1,正如责任链所示,拥有不同种类的手是可以的;你可以阅读你的文件,根据需要使用许多参数创建不同类型的牌。
由于原因2,您可以查看其他解决方案。一个是让你的Hand
类触发事件(例如:当它被识别时),你的应用程序可以将这些手注册到其他类来监听事件。另一个班级也应负责从您正在阅读的文件中收集必要的数据。由于手不是(或不应该)负责收集统计数据,所以底线是您需要处理其他内容。
一个包 =连贯的API和功能
一个类 =连贯的功能(一只手是一只手,而不是一个统计容器)
一种方法 =一种(单一)功能(如果方法需要处理多个功能,将这些功能分解为单独的私有方法,并从公共方法中调用它们)
我在这里给你一个通用的答案,因为原因1 和原因2 并不具体。