Un esempio di pattern Memento: è corretto?

0

Dopo questa query sul pattern di memento, ho provato a mettere il mio comprensione da testare.

Memento pattern stands for three things:

  1. Saving state of the "memento" object for its successful retrieval
  2. Saving carefully each valid "state" of the memento
  3. Encapsulating the saved states from the change inducer so that each state remains unaltered

Ho raggiunto questi tre con il mio design?

Problema
Questo è un gioco a giocatore zero in cui il programma è inizializzato con un particolare set di pedine degli scacchi - il cavaliere e la regina. Quindi il programma deve continuare ad aggiungere set di pedoni o cavalieri e regine in modo che ogni pedone sia "sicuro" per la prossima mossa di ogni altro pedone.

La condizione è che entrambi i pedoni debbano essere piazzati, o che nessuno di loro debba essere piazzato. La scacchiera con il maggior numero di cavalieri e regine non in conflitto dovrebbe essere restituita.

Implementazione Ho 4 classi per questo:

  1. protected ChessBoard (il Memento)

    private int [][] ChessBoard;
    
    public void ChessBoard();
    protected void SetChessBoard();
    protected void GetChessBoard(int);
    
  2. public Pawn Questo non è correlato al ricordo. Contiene informazioni sui pedoni

    public enum PawnType: int
    {
        Empty = 0,
        Queen = 1,
        Knight = 2,
    }
    //This returns a value that shown if the pawn can be placed safely
    public bool IsSafeToAddPawn(PawnType);
    
  3. public CareTaker Corrisponde a custode del ricordo

    Questo è un array di interi a doppia dimensione che mantiene una traccia di tutti gli stati. La ragione per cui l'array 2D è tenere traccia di quanti stati sono memorizzati e quale stato è attualmente attivo. Un esempio:

    0 -2
    1 -1
    2 0 - Questo è lo stato corrente. Con il secondo indice 0 /
    3 1 - Questo stato è stato salvato, ma è stato annullato

    private int [][]State;
    private ChessBoard [] MChessBoard;
    
    //This gets the chessboard at the position requested and assigns it to originator
    public ChessBoard GetChessBoard(int);
    
    //This overwrites the chessboard at given position
    public void SetChessBoard(ChessBoard, int);
    
    private int [][]State;
    
  4. public PlayGame (Questo è il mittente)

    private bool status;
    private ChessBoard oChessBoard;
    
    //This sets the state of chessboard at position specified public
    SetChessBoard(ChessBoard, int);
    
    //This gets the state of chessboard at position specified public
    ChessBoard GetChessBoard(int);
    
    //This function tries to place both the pawns and returns the status of this attempt
    public bool PlacePawns(Pawn);
    

Modifica dopo la discussione con Kevin

Il modo in cui sto cercando di applicare modelli di progettazione ai miei problemi non è corretto. In un certo modo mi aiuta a capire "come" "implementarlo". Sì. Ma poi, questo non è il suo uso ideale. Potrei anche semplificare il mio problema di "apprendimento" e utilizzare i miei libri di testo.

Fai riferimento anche a questo domanda su programmers.stackoverflow e tutte le discussioni!

    
posta TheSilverBullet 28.08.2012 - 14:00
fonte

2 risposte

3

Non hai bisogno di un pattern Memento per questo problema, semplicemente un semplice backtracking. Non ho capito bene il tuo uso di "pedina", ma in pratica hai messo qualcosa nel primo posto legale. Hai solo bisogno di ricordare la posizione attuale e il migliore finora. Quando non puoi aggiungere altro alla lavagna, salva la posizione se è migliore della precedente. Quindi, annulla l'ultimo posizionamento e prova il punto successivo.

    
risposta data 28.08.2012 - 19:28
fonte
0

Non sono completamente d'accordo con la tua affermazione su ciò che rappresenta il modello di Memento.

L'idea alla base di questo modello è che esiste un oggetto ("originatore") che ha uno stato interno. C'è un altro oggetto (il "custode") che vuole eseguire un'azione sul mittente, ma vuole essere in grado di annullare la modifica.

La prima cosa che fa Caretaker è chiedere un oggetto Memento all'originatore (che è una rappresentazione del suo stato interno) e quindi eseguire l'operazione che cambierà lo stato interno del mittente. Se il custode non è soddisfatto del risultato, può ripristinare le modifiche nello stato interno del generatore utilizzando il Memento. L'Originatore accetta il Memento e ripristina il suo stato interno.

Pertanto, ciò che si salva è lo stato interno di Originator incapsulato in un oggetto chiamato Memento.

Nel tuo programma dovrebbe essere il custode a eseguire le operazioni su Originator e non solo una struttura dati per memorizzare gli stati. L'unico requisito è quello di memorizzare l'ultimo Memento per supportare "Annulla". Tuttavia è possibile supportare operazioni di "annullamento" multiple con qualsiasi struttura di dati LIFO in cui è possibile "pop" e "push" elementi. Pertanto, il secondo indice non è necessario, ma posso immaginare che puoi usarlo in qualche modo per supportare le operazioni "REDO" (e quindi non ha senso in un gioco a giocatore zero).

In conclusione, penso che il tuo design sia sbagliato anche se ha senso applicare il pattern Memento in questo problema.

    
risposta data 02.09.2014 - 13:05
fonte

Leggi altre domande sui tag