interface IState{
public function reservation();
public function checkin();
public function checkout();
}
class ReservState implements IState{
private $subject;
public function __construct(Hotel $subject){
$this->subject = $subject;
}
public function reservation(){
echo '予約済みです。<br>';
}
public function checkin(){
echo 'チェックインし、滞在状態になりました。<br>';
$this->subject->changeState(new StayState($this->subject));
}
public function checkout(){
echo '予約状態でチェックアウトはできません。<br>';
}
}
class StayState implements IState{
private $subject;
public function __construct(Hotel $subject){
$this->subject = $subject;
}
public function reservation(){
echo '別件で予約状態にします。<br>';
}
public function checkin(){
echo 'チェックイン済みです。<br>';
}
public function checkout(){
echo 'チェックアウトして、未予約状態になりました。<br>';
$this->subject->changeState(new UnreservState($this->subject));
}
}
class UnreservState implements IState{
private $subject;
public function __construct(Hotel $subject){
$this->subject = $subject;
}
public function reservation(){
echo '予約して、予約状態になりました。<br>';
$this->subject->changeState(new ReservState($this->subject));
}
public function checkin(){
echo '空き室があれば滞在状態になります。空き室がなければ未予約状態のままです。<br>';
}
public function checkout(){
echo 'チェックインしていないのでチェックアウトできません。<br>';
}
}
class Hotel{
private $state; // <IState>
public function __construct(){
$this->state = new UnreservState($this); // 未予約状態
}
/**
* 状態を変更する
* @param IState $state 状態クラスのインスタンス
*/
public function changeState(IState $state){
$this->state = $state;
}
public function reserveAction(){
$this->state->reservation();
}
public function checkinAction(){
$this->state->checkin();
}
public function checkoutAction(){
$this->state->checkout();
}
}
$hotel = new Hotel();
$hotel->reserveAction();
$hotel->checkinAction();
$hotel->checkinAction();
$hotel->checkoutAction();
出力
予約して、予約状態になりました。