2010-01-28 10 views
8

Ecco un frammento di codice:Java ha un equivalente di riferimento const?

//Game board is made up of Squares. A player can place GamePieces on a Square. 
    public class CheckersBoard 
    { 
     public boolean PlaceGamePiece(GamePiece gamePiece, int nRow, int nColumn) { 
      return m_theGameBoard[nRow][nColumn].PlaceGamePiece(gamePiece); 
     } 

     private Square[][] m_theGameBoard; 
    } 

diciamo sto testando il metodo PlaceGamePiece (utilizzando JUnit) e ho bisogno di accedere al m_theGameBoard modo che io possa vedere le cose e verificare la GamePiece è stata posta sul corretto Square e ha i dati corretti.

In C++ avrei neanche fare la classe di test un amico in modo che possa accedere al membro privato m_theGameBoard, o mi piacerebbe avere una funzione che restituisce un GameBoard const che non può essere modificato (perché è const):

const GameBoard& GetGameBoard() const { return m_theGameBoard; } 

Ora posso fare tutto ciò che è necessario controllare sul tabellone, ma non posso modificare il tabellone perché è const.

Java non supporta il ritorno dei riferimenti const o delle classi friend. Quindi la mia domanda è qual è il modo standard Java di farlo ?? Devo solo fornire un sacco di ottenere accessor che mi permettono di controllare i dati sul Square?

AGGIORNAMENTO: Ho finito per scrivere un metodo GetPiece come suggerito da Kaleb Brasee.

public GamePiece GetGamePiece(Point pt) { 
    return new GamePiece(m_theGameBoard[pt.GetRow()][pt.GetColumn()]); 
} 

Avviso Creo un nuovo oggetto GamePiece e lo restituisco. Non sto restituendo il riferimento interno di GameBoards, quindi nessuno può modificare il gameboard perché ne ha solo una copia! Bello! Grazie per l'aiuto ragazzi, alcuni ottimi consigli.

FYI: Continuo a cambiare i nomi degli oggetti quando li invio qui, scusa se questo ha confuso nessuno.

risposta

3

Definire la variabile come protected, in modo che se il test dell'unità si trova nello stesso pacchetto, può accedervi.

Tuttavia, vorrei solo aggiungere un metodo pubblico getPiece(int row, int col) che restituisce il pezzo su quel quadrato (o null se non c'è nessun pezzo lì). È probabile che avrai comunque bisogno di un metodo del genere, e potresti usarlo nei tuoi test.

+0

Ho l'impressione che protetto sia la stessa cosa dell'amico di c. – Karl

+0

Ma cosa succede se una classe che lavora con la scheda ha bisogno di mostrare tutti i pezzi sulla scacchiera (come una classe GUI che deve mostrare tutti i pezzi sulla scacchiera) - come faresti senza un metodo per ottenere pezzi? Nella mia app di scacchi ho un metodo 'Board.pieceOn (Square)' che restituisce un pezzo se c'è qualche pezzo, o null se il quadrato è vuoto. Sarebbe meglio restituire una mappa dei quadrati occupati mappati su Pezzi? –

+0

http://www.javaworld.com/javaworld/jw-01-2004/jw-0102-toolbox.html Perché gli oggetti, dato un contesto grafico, non si disegnano da soli? Aggiungi un metodo 'draw' ai pezzi (o una sottoclasse di ogni pezzo, se preferisci mantenere separato il codice dell'interfaccia utente). Penso che 'board.draw (graphics)' e 'piece.draw (graphics)' abbiano perfettamente senso. Combina questo con la tecnica di Holub delineata nel link e hai una buona soluzione che evita di rompere l'incapsulamento. –

1

Sì. Le scelte fondamentalmente si riducono a uno avere:

Square getSquareAtLocation(int row, int col) { ... }; 

o utilizzando una delle collezioni Java che si potrebbe poi passare attraverso Collections.unmodifiableList (...)

(si noti che se si è utilizzato un elenco multidimensionale , dovresti stare attento anche a completare le Liste interne per assicurarti che non siano modificabili)

Se questo verrà usato solo per i test, potresti anche creare una funzione che restituisca un copia profonda dell'array.

2

Il modificatore di accesso predefinito per un metodo o una proprietà è "protetto da pacchetto", che significa "visibile solo all'interno del pacchetto". Pertanto, è possibile emulare la semantica di "amicizia", ​​mantenendo una base di codice separata per i test, avendo due cartelle di origine distinte, ma con la stessa struttura di pacchetto.

src 
|--com 
    | 
    --cchampion 
     | 
     --MyClass.java 
tests 
|--com 
    | 
    --cchampion 
     | 
     --TestMyClass.java 

Quindi, in MyClass.java

public class MyClass { 
    private int nonTestedThing; 
    int[][] testedThing; // this is visible to TestMyClass 
    // or 
    // protected int[][] testedThing; 
    // if you want it visible to kids 
} 

Questo non è l'ideale in alcun senso, ma è un modo per farlo.

Problemi correlati