state gummball
This commit is contained in:
parent
41ff6962c3
commit
e93f2da595
|
@ -11,6 +11,7 @@
|
|||
3. [Команда](command/)
|
||||
4. [Шаблонный метод](templatemethod/)
|
||||
5. [Итератор](iterator/)
|
||||
6. [Состояние](state/)
|
||||
|
||||
### Структурные
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Состояние
|
||||
|
||||
Поведенческий паттерн проектирования, который позволяет объектам менять поведение в зависимости от своего состояния. Извне создаётся впечатление, что изменился класс объекта.
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module state;
|
||||
|
||||
interface State
|
||||
{
|
||||
void insertQuarter();
|
||||
void ejectQuarter();
|
||||
void turnCrank();
|
||||
void dispense();
|
||||
|
||||
void refill();
|
||||
}
|
Reference in New Issue