State Pattern
State Pattern - אחד הפאטרנים הכי חשובים שיש. דוגמה של כספומט:
בדרך כלל State Pattern מורכב משלושה חלקים:
1. Context - ישות שמשתמש ניגש אליה:
- public class ATM {
- public ATMState currentState = null;
- public ATM() {
- currentState = new NoCardState(1000, this);
- }
- public void StartTheATM() {
- while (true) {
- Console.WriteLine(currentState.GetNextScreen());
- }
- }
- }
2. State - זה Interface או Abstract class שמגדיר כל המצבים האפשריים של Context:
- public abstract class ATMState {
- public ATM Atm { get; get; }
- public int DummyCashPresent { get;set; } = 1000;
- public abstract string GetNextScreen();
- }
3. Concrete State - מצב של Context. לכל מצב יהיה class משלו.:
- public class NoCardState : ATMState {
- public NoCardState(ATMState state):this(state.DummyCashPresent, state.Atm) {
- }
- public NoCardState(int amountRemaining, ATM atmBeingUsed) {
- this.Atm = atmBeingUsed;
- this.DummyCashPresent = amountRemaining;
- }
- public override string GetNextScreen() {
- Console.WriteLine("Please enter your pin");
- string userInput = Console.ReadLine();
- if (userInput.Trim() == "1234") {
- UpdateState();
- return "Enter the amount to withdraw";
- }
- return "Invalid PIN";
- }
- private void UpdateState() {
- Atm.currentState = new CardValidatedState(this);
- }
- }
- public class CardValidatedState : ATMState {
- public CardValidatedState(ATMState state):this(state.DummyCashPresent, state.Atm){
- }
- public CardValidatedState(int amountRemaining, ATM atmBeingUsed) {
- this.Atm = atmBeingUsed;
- this.DummyCashPresent = amountRemaining;
- }
- public override string GetNextScreen() {
- string userInput = Console.ReadLine();
- int requestAmount;
- bool result = Int32.TryParse(userInput, out requestAmount);
- if (result == true) {
- if (this.DummyCashPresent < requestAmount) {
- return "Amount not present";
- }
- this.DummyCashPresent -= requestAmount;
- UpdateState();
- return $"Amount of {requestAmount} has been withdrawn. Press Enter to proceed";
- }
- return "Invalid amount";
- }
- private void UpdateState() {
- Atm.currentState = new NoCashState(this);
- }
- }