Search code examples
javadesign-patternsmethodsundo

Allow reverse operation in undo only


I'm trying to implement simple Solitaire game.

Now let's assume we have a class called SourceCardDeck which represents source deck of cards. This class has an ability to pop one card, but it doesn't have an ability to push card back (which is desired, as users should not be able to store card on the source deck).

But now I want to implement an undo operation!

How can I do that without any method to push card back? I've heard about Command pattern, but it works only with reverse method available. Also what about Card and its ability to turn up? Should card have method to turn down? User usually cannot turn card down again. But in undo it's needed.

How to make this proper and clean way?


Solution

  • A pretty broad question, thus a broad answer, meant to get you going: basically you are asking: how can I "restore" the status of an object in a way that conflicts with the public API of that object?

    There are two options here:

    • You re-think your API. For example you could have that special card stack implement a certain interface. The interface only exposes methods to take cards from the stack (thus preventing accidental pushing back). But the class implementing that interface might also implement another interface; which allows for push-back. So, "most" of your code uses the take-only interface "view"; and only that part that needs to push-back works on the other interface.
    • When you can't change the status of a single object - you could simply "persist" the state of all objects. For each state change. And "undo" means: un-persisting all objects to prior content. In other words: you could serialize all objects in your game upon a state change; and "undo" means: de-serialize all objects.

    Both approaches have their pros and cons; and as this is your project, I leave discussing those aspects and driving a decision as exercise to the reader.

    Finally: a card should not know about being turned down or note. A card is just a card. Just think about how the real world domain you are trying to model. A card in a card game doesn't change a bit. It is always just a piece of cardboard with something printed on it. It has no state. The only things that have state: the various piles which contain card objects.