Last active
December 4, 2023 12:01
-
-
Save kishankg/574791e75fdcedddc96394a389f0d7e0 to your computer and use it in GitHub Desktop.
Command Design Pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Stack; | |
// Receiver: TextEditor | |
class TextEditor { | |
private StringBuilder text = new StringBuilder(); | |
void insertText(String insertedText) { | |
text.append(insertedText); | |
} | |
void deleteText(int length) { | |
int endIndex = text.length() - length; | |
if (endIndex >= 0) { | |
text.delete(endIndex, text.length()); | |
} | |
} | |
void displayText() { | |
System.out.println("Current Text: " + text.toString()); | |
} | |
} | |
// Command Interface | |
interface Command { | |
void execute(); | |
void undo(); | |
} | |
// Concrete Command: InsertCommand | |
class InsertCommand implements Command { | |
private TextEditor textEditor; | |
private String insertedText; | |
InsertCommand(TextEditor textEditor, String insertedText) { | |
this.textEditor = textEditor; | |
this.insertedText = insertedText; | |
} | |
@Override | |
public void execute() { | |
textEditor.insertText(insertedText); | |
} | |
@Override | |
public void undo() { | |
textEditor.deleteText(insertedText.length()); | |
} | |
} | |
// Concrete Command: DeleteCommand | |
class DeleteCommand implements Command { | |
private TextEditor textEditor; | |
private int deletedLength; | |
DeleteCommand(TextEditor textEditor, int deletedLength) { | |
this.textEditor = textEditor; | |
this.deletedLength = deletedLength; | |
} | |
@Override | |
public void execute() { | |
textEditor.deleteText(deletedLength); | |
} | |
@Override | |
public void undo() { | |
// Reinsert the deleted text for undo | |
textEditor.insertText("Deleted Text"); | |
} | |
} | |
// Invoker: TextOperationInvoker | |
class TextOperationInvoker { | |
private Stack<Command> undoStack = new Stack<>(); | |
private Stack<Command> redoStack = new Stack<>(); | |
void executeCommand(Command command) { | |
command.execute(); | |
undoStack.push(command); | |
redoStack.clear(); // Clear redo stack after executing a new command | |
} | |
void undo() { | |
if (!undoStack.isEmpty()) { | |
Command undoneCommand = undoStack.pop(); | |
undoneCommand.undo(); | |
redoStack.push(undoneCommand); | |
} | |
} | |
void redo() { | |
if (!redoStack.isEmpty()) { | |
Command redoneCommand = redoStack.pop(); | |
redoneCommand.execute(); | |
undoStack.push(redoneCommand); | |
} | |
} | |
} | |
// Client Code | |
public class TextEditorApp { | |
public static void main(String[] args) { | |
TextEditor textEditor = new TextEditor(); | |
TextOperationInvoker operationInvoker = new TextOperationInvoker(); | |
// Inserting and displaying text | |
operationInvoker.executeCommand(new InsertCommand(textEditor, "Hello, ")); | |
textEditor.displayText(); | |
// Deleting and displaying text | |
operationInvoker.executeCommand(new DeleteCommand(textEditor, 5)); | |
textEditor.displayText(); | |
// Undoing the last operation | |
operationInvoker.undo(); | |
textEditor.displayText(); | |
// Redoing the undone operation | |
operationInvoker.redo(); | |
textEditor.displayText(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Stack; | |
// Receiver: Account | |
class Account { | |
private String accountHolder; | |
private double balance; | |
Account(String accountHolder, double initialBalance) { | |
this.accountHolder = accountHolder; | |
this.balance = initialBalance; | |
} | |
void deposit(double amount) { | |
balance += amount; | |
System.out.println("Deposited $" + amount + ". New balance: $" + balance); | |
} | |
void withdraw(double amount) { | |
if (amount <= balance) { | |
balance -= amount; | |
System.out.println("Withdrawn $" + amount + ". New balance: $" + balance); | |
} else { | |
System.out.println("Insufficient funds for withdrawal."); | |
} | |
} | |
void displayBalance() { | |
System.out.println("Current balance for " + accountHolder + ": $" + balance); | |
} | |
} | |
// Command Interface | |
interface TransactionCommand { | |
void execute(); | |
void undo(); | |
} | |
// Concrete Command: DepositCommand | |
class DepositCommand implements TransactionCommand { | |
private Account account; | |
private double amount; | |
DepositCommand(Account account, double amount) { | |
this.account = account; | |
this.amount = amount; | |
} | |
@Override | |
public void execute() { | |
account.deposit(amount); | |
} | |
@Override | |
public void undo() { | |
account.withdraw(amount); // Undoing deposit is treated as a withdrawal | |
} | |
} | |
// Concrete Command: WithdrawCommand | |
class WithdrawCommand implements TransactionCommand { | |
private Account account; | |
private double amount; | |
WithdrawCommand(Account account, double amount) { | |
this.account = account; | |
this.amount = amount; | |
} | |
@Override | |
public void execute() { | |
account.withdraw(amount); | |
} | |
@Override | |
public void undo() { | |
account.deposit(amount); // Undoing withdrawal is treated as a deposit | |
} | |
} | |
// Concrete Command: TransferCommand | |
class TransferCommand implements TransactionCommand { | |
private Account sourceAccount; | |
private Account destinationAccount; | |
private double amount; | |
TransferCommand(Account sourceAccount, Account destinationAccount, double amount) { | |
this.sourceAccount = sourceAccount; | |
this.destinationAccount = destinationAccount; | |
this.amount = amount; | |
} | |
@Override | |
public void execute() { | |
sourceAccount.withdraw(amount); | |
destinationAccount.deposit(amount); | |
System.out.println("Transferred $" + amount + " from " + sourceAccount.getAccountHolder() + | |
" to " + destinationAccount.getAccountHolder()); | |
} | |
@Override | |
public void undo() { | |
destinationAccount.withdraw(amount); | |
sourceAccount.deposit(amount); | |
System.out.println("Undone transfer of $" + amount + " from " + sourceAccount.getAccountHolder() + | |
" to " + destinationAccount.getAccountHolder()); | |
} | |
} | |
// Invoker: TransactionManager | |
class TransactionManager { | |
private Stack<TransactionCommand> transactionStack = new Stack<>(); | |
private Stack<TransactionCommand> redoStack = new Stack<>(); | |
void executeTransaction(TransactionCommand transactionCommand) { | |
transactionCommand.execute(); | |
transactionStack.push(transactionCommand); | |
redoStack.clear(); // Clear redo stack after executing a new transaction | |
} | |
void undoLastTransaction() { | |
if (!transactionStack.isEmpty()) { | |
TransactionCommand lastTransaction = transactionStack.pop(); | |
lastTransaction.undo(); | |
redoStack.push(lastTransaction); | |
} | |
} | |
void redoLastTransaction() { | |
if (!redoStack.isEmpty()) { | |
TransactionCommand redoTransaction = redoStack.pop(); | |
redoTransaction.execute(); | |
transactionStack.push(redoTransaction); | |
} | |
} | |
} | |
// Client Code | |
public class BankingApp { | |
public static void main(String[] args) { | |
Account aliceAccount = new Account("Alice", 1000.0); | |
Account bobAccount = new Account("Bob", 500.0); | |
TransactionManager transactionManager = new TransactionManager(); | |
// Performing transactions | |
transactionManager.executeTransaction(new DepositCommand(aliceAccount, 200.0)); | |
transactionManager.executeTransaction(new WithdrawCommand(bobAccount, 100.0)); | |
transactionManager.executeTransaction(new TransferCommand(aliceAccount, bobAccount, 300.0)); | |
// Displaying account balances | |
aliceAccount.displayBalance(); | |
bobAccount.displayBalance(); | |
// Undoing the last transaction | |
transactionManager.undoLastTransaction(); | |
aliceAccount.displayBalance(); | |
bobAccount.displayBalance(); | |
// Redoing the undone transaction | |
transactionManager.redoLastTransaction(); | |
aliceAccount.displayBalance(); | |
bobAccount.displayBalance(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment