state gummball

This commit is contained in:
Alexander Zhirov 2022-11-20 02:40:58 +03:00
parent 41ff6962c3
commit e93f2da595
11 changed files with 534 additions and 0 deletions

View File

@ -11,6 +11,7 @@
3. [Команда](command/)
4. [Шаблонный метод](templatemethod/)
5. [Итератор](iterator/)
6. [Состояние](state/)
### Структурные

5
state/README.md Normal file
View File

@ -0,0 +1,5 @@
# Состояние
Поведенческий паттерн проектирования, который позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся впечатление, что изменился класс объекта.

View File

@ -0,0 +1,40 @@
module app;
import gumballmachine;
import std.stdio : writeln;
void main()
{
GumballMachine gumballMachine = new GumballMachine(5);
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.ejectQuarter();
gumballMachine.turnCrank();
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.ejectQuarter();
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
writeln(gumballMachine);
}

View File

@ -0,0 +1,155 @@
module gumballmachine;
import std.stdio : writeln;
import std.conv : to;
class GumballMachine
{
static const int SOLD_OUT = 0; // нет шариков
static const int NO_QUARTER = 1; // нет монетки
static const int HAS_QUARTER = 2; // есть монетка
static const int SOLD = 3; // шарик продан
int state = SOLD_OUT;
int count = 0;
this(int count)
{
this.count = count;
if (count > 0)
{
state = NO_QUARTER;
}
}
void insertQuarter()
{
if (state == HAS_QUARTER)
{
writeln("You can't insert another quarter");
}
else if (state == NO_QUARTER)
{
state = HAS_QUARTER;
writeln("You inserted a quarter");
}
else if (state == SOLD_OUT)
{
writeln("You can't insert a quarter, the machine is sold out");
}
else if (state == SOLD)
{
writeln("Please wait, we're already giving you a gumball");
}
}
void ejectQuarter()
{
if (state == HAS_QUARTER)
{
writeln("Quarter returned");
state = NO_QUARTER;
}
else if (state == NO_QUARTER)
{
writeln("You haven't inserted a quarter");
}
else if (state == SOLD)
{
writeln("Sorry, you already turned the crank");
}
else if (state == SOLD_OUT)
{
writeln("You can't eject, you haven't inserted a quarter yet");
}
}
void turnCrank()
{
if (state == SOLD)
{
writeln("Turning twice doesn't get you another gumball!");
}
else if (state == NO_QUARTER)
{
writeln("You turned but there's no quarter");
}
else if (state == SOLD_OUT)
{
writeln("You turned, but there are no gumballs");
}
else if (state == HAS_QUARTER)
{
writeln("You turned...");
state = SOLD;
dispense();
}
}
private void dispense()
{
if (state == SOLD)
{
writeln("A gumball comes rolling out the slot");
--count;
if (count == 0)
{
writeln("Oops, out of gumballs!");
state = SOLD_OUT;
}
else
{
state = NO_QUARTER;
}
}
else if (state == NO_QUARTER)
{
writeln("You need to pay first");
}
else if (state == SOLD_OUT)
{
writeln("No gumball dispensed");
}
else if (state == HAS_QUARTER)
{
writeln("No gumball dispensed");
}
}
void refill(int numGumBalls)
{
this.count = numGumBalls;
state = NO_QUARTER;
}
override string toString() const
{
string s;
s ~= "\nMighty Gumball, Inc.";
s ~= "\nJava-enabled Standing Gumball Model #2004\n";
s ~= "Inventory: " ~ count.to!string ~ " gumball";
if (count != 1)
{
s ~= "s";
}
s ~= "\nMachine is ";
if (state == SOLD_OUT)
{
s ~= "sold out";
}
else if (state == NO_QUARTER)
{
s ~= "waiting for quarter";
}
else if (state == HAS_QUARTER)
{
s ~= "waiting for turn of crank";
}
else if (state == SOLD)
{
s ~= "delivering a gumball";
}
s ~= "\n";
return s;
}
}

View File

@ -0,0 +1,27 @@
module app;
import gumballmachine;
import std.stdio : writeln;
void main()
{
GumballMachine gumballMachine = new GumballMachine(2);
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
writeln(gumballMachine);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
gumballMachine.refill(5);
gumballMachine.insertQuarter();
gumballMachine.turnCrank();
writeln(gumballMachine);
}

View File

@ -0,0 +1,116 @@
module gumballmachine;
import std.stdio : writeln;
import std.conv : to;
import soldoutstate, noquarterstate, hasquarterstate, soldstate, state;
class GumballMachine
{
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State state;
int count = 0;
this(int numberGumballs)
{
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
this.count = numberGumballs;
if (numberGumballs > 0)
{
state = noQuarterState;
}
else
{
state = soldOutState;
}
}
void insertQuarter()
{
state.insertQuarter();
}
void ejectQuarter()
{
state.ejectQuarter();
}
void turnCrank()
{
state.turnCrank();
state.dispense();
}
void releaseBall()
{
writeln("A gumball comes rolling out the slot...");
if (count > 0)
{
count = count - 1;
}
}
int getCount()
{
return count;
}
void refill(int count)
{
this.count += count;
writeln("The gumball machine was just refilled; its new count is: ", this.count);
state.refill();
}
void setState(State state)
{
this.state = state;
}
State getState()
{
return state;
}
State getSoldOutState()
{
return soldOutState;
}
State getNoQuarterState()
{
return noQuarterState;
}
State getHasQuarterState()
{
return hasQuarterState;
}
State getSoldState()
{
return soldState;
}
override string toString() const
{
string s;
s ~= "\nMighty Gumball, Inc.";
s ~= "\nJava-enabled Standing Gumball Model #2004";
s ~= "\nInventory: " ~ count.to!string ~ " gumball";
if (count != 1)
{
s ~= "s";
}
s ~= "\n";
s ~= "Machine is " ~ state.to!string ~ "\n";
return s;
}
}

View File

@ -0,0 +1,43 @@
module hasquarterstate;
import std.stdio : writeln;
import state, gumballmachine;
class HasQuarterState : State
{
GumballMachine gumballMachine;
this(GumballMachine gumballMachine)
{
this.gumballMachine = gumballMachine;
}
void insertQuarter()
{
writeln("You can't insert another quarter");
}
void ejectQuarter()
{
writeln("Quarter returned");
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
void turnCrank()
{
writeln("You turned...");
gumballMachine.setState(gumballMachine.getSoldState());
}
void dispense()
{
writeln("No gumball dispensed");
}
void refill() {}
override string toString() const
{
return "waiting for turn of crank";
}
}

View File

@ -0,0 +1,42 @@
module noquarterstate;
import std.stdio : writeln;
import state, gumballmachine;
class NoQuarterState : State
{
GumballMachine gumballMachine;
this(GumballMachine gumballMachine)
{
this.gumballMachine = gumballMachine;
}
void insertQuarter()
{
writeln("You inserted a quarter");
gumballMachine.setState(gumballMachine.getHasQuarterState());
}
void ejectQuarter()
{
writeln("You haven't inserted a quarter");
}
void turnCrank()
{
writeln("You turned, but there's no quarter");
}
void dispense()
{
writeln("You need to pay first");
}
void refill() { }
override string toString() const
{
return "waiting for quarter";
}
}

View File

@ -0,0 +1,44 @@
module soldoutstate;
import std.stdio : writeln;
import state, gumballmachine;
class SoldOutState : State
{
GumballMachine gumballMachine;
this(GumballMachine gumballMachine)
{
this.gumballMachine = gumballMachine;
}
void insertQuarter()
{
writeln("You can't insert a quarter, the machine is sold out");
}
void ejectQuarter()
{
writeln("You can't eject, you haven't inserted a quarter yet");
}
void turnCrank()
{
writeln("You turned, but there are no gumballs");
}
void dispense()
{
writeln("No gumball dispensed");
}
void refill()
{
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
override string toString() const
{
return "sold out";
}
}

View File

@ -0,0 +1,50 @@
module soldstate;
import std.stdio : writeln;
import state, gumballmachine;
class SoldState : State
{
GumballMachine gumballMachine;
this(GumballMachine gumballMachine)
{
this.gumballMachine = gumballMachine;
}
void insertQuarter()
{
writeln("Please wait, we're already giving you a gumball");
}
void ejectQuarter()
{
writeln("Sorry, you already turned the crank");
}
void turnCrank()
{
writeln("Turning twice doesn't get you another gumball!");
}
void dispense()
{
gumballMachine.releaseBall();
if (gumballMachine.getCount() > 0)
{
gumballMachine.setState(gumballMachine.getNoQuarterState());
}
else
{
writeln("Oops, out of gumballs!");
gumballMachine.setState(gumballMachine.getSoldOutState());
}
}
void refill() {}
override string toString() const
{
return "dispensing a gumball";
}
}

View File

@ -0,0 +1,11 @@
module state;
interface State
{
void insertQuarter();
void ejectQuarter();
void turnCrank();
void dispense();
void refill();
}