该问题仅用于询问如何处理对象的方法,该方法检查与调用方法相同的条件并引发相同的异常类型。由于问题的性质,它变成了有关类设计的问题。
我正在为国际象棋程序设计类设计。我最初使用允许您Chessboard
个片段的方法制作了一个put
类。原因是:
这是一成不变的,我发现反复创建新的木板对象只是为了初始化它似乎是不必要的。
理想情况下,该板应该一块装满,然后通过Chessboard
的界面对板进行进一步的更改。
我做了一个可变的PieceSet
类,该类在Chessboard
构造函数中传递。
// Showing as interface instead of class, because implementation is not important
public interface PieceSet
{
void putBishop(Square square, Color color) throws UndefinedSquareException;
void putKing(Square square, Color color) throws UndefinedSquareException;
void putKnight(Square square, Color color) throws UndefinedSquareException;
void putPawn(Square square, Color color) throws UndefinedSquareException;
void putQueen(Square square, Color color) throws UndefinedSquareException;
void putRook(Square square, Color color) throws UndefinedSquareException;
void removePiece(Square square);
void relocate(Square fromSquare, Square toSquare) throws UndefinedSquareException;
}
在
PieceSet
的实现中,这些方法将使用防护来检查空平方if(null == square)
throw new UndefinedSquareException(...);
例如,
Chessboard
类将使用PieceSet
类,如下所示:public final class Chessboard
{
private PieceSet pieces;
public Chessboard()
{
this.pieces = new PieceSet();
}
public Chessboard(PieceSet initialPieces)
{
this.pieces = new PieceSet(initialPieces);
}
public Chessboard removePiece(Square square) throws UndefinedSquareException
{
/*
* Check for null here and throw exception??
* PieceSet does the same thing.
*/
PieceSet newPieces = new PieceSet(this.pieces);
newPieces.removePiece(square);
return new Chessboard(newPieces);
}
public Chessboard movePiece(Square fromSquare, Square toSquare) throws UndefinedSquareException
{
/*
* Check for null here and throw exception??
* PieceSet does the same thing.
*/
PieceSet newPieces = new PieceSet(this.pieces);
newPieces.relocate(fromSquare, toSquare);
return new Chessboard(newPieces);
}
}
然后的问题是,由于
Chessboard
也接收Square
类型的参数,并且它们不应该是null
,我是否还要在Chessboard
的removePiece
和movePiece
方法中设置防护措施?if(null == square)
throw new UndefinedSquareException(...);
另一个想法
我的另一个想法是将
PieceSet
建模为Chessboard
的构建器(尽管PieceSet
可能不再是一个好名字,但我不会更改示例的名称)。我以为,由于PieceSet
的最初想法是使用它来创建填充的Chessboard
,所以我将使PieceSet
负责而不是将其传递给Chessboard
。public interface PieceSet
{
putBishop(Square square, Color color) throws UndefinedSquareException;
putKing(Square square, Color color) throws UndefinedSquareException;
// Same from above, etc. EXCEPT no remove or relocate methods
// This is new
Chessboard createBoard();
}
// The Chessboard doesn't have to use PieceSet. It can be implemented using any data structure to store pieces.
public final class Chessboard
{
private Map<Square, Piece>pieces;
public Chessboard(Map<Square, Piece> initialPieces)
{
this.pieces = new HashMap<Square, Piece>(initialPieces);
}
public Chessboard removePiece(Square square)
{
// No more duplication of checking for null square, and throwing exception
}
public Chessboard movePiece(Square fromSquare, Square toSquare)
{
// No more duplication of checking for null square, and throwing exception
}
}
最佳答案
总的来说,我们强烈认为接口应该抛出一个检查异常。此外,我们要装饰提供该接口实现的策略对象。最后,我们认为接口中的已检查异常适用于装饰器的调用者。在这种情况下,如果需要将委托抛出的异常传递给装饰器的调用者,那么可以,您将在装饰器中抛出相同的异常。
但具体针对Chessboard问题:我不确定我是否同意UndefinedSquareException甚至应该是经过检查的异常。为什么使用此API的用户曾经提供对空Square的引用,或未由此Chessboard管理的Square的引用,并希望恢复?结果,我倾向于认为UndefinedSquareException扩展了RuntimeException,根本不需要在您的签名中,或者Chessboard捕获了来自PieceSet的已检查异常并在其位置抛出RuntimeException。
希望这对您有所帮助-乐于阅读您的问题并思考问题。
关于java - 当委托(delegate)方法具有相同的防护时,如何处理防护子句并引发异常?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20448044/