Рубрики
Uncategorized

Шаблоны проектирования PHP – Шаблоны состояний

Автор оригинала: David Wong.

Предисловие

Шаблон проектирования состояния является одним из наиболее привлекательных шаблонов, предложенных Gof, а также одним из наиболее полезных шаблонов. В игре обычно используется режим состояния, потому что объект в игре часто очень часто меняет состояние. Функция режима состояния состоит в том, чтобы позволить объекту изменять свое поведение при изменении состояния. Многие другие приложения для моделирования (не обязательно игры) также зависят от режима состояния. В этой статье мы поговорим об этом и проиллюстрируем примерами. Согласно традиционному мышлению, если существует более одного состояния, оно обычно обрабатывается с помощью if, else, if, switch, но такой код выглядит крайне некрасиво, самое главное, что нет расширяемости, ремонтопригодности, возможности повторного использования, и будет ситуация “нажать один спусковой крючок и переместить все тело”. Если вы инкапсулируете эти состояния,вы можете значительно уменьшить количество суждений,тогда вам придется использовать режим состояния.

Эскизный проект

анализ требований

1. Соответствие коду обладает высокой расширяемостью, ремонтопригодностью и возможностью повторного использования. Это может устранить ситуацию “нажатия на спусковой крючок и перемещения всего тела”. 2. Сократите использование большого количества суждений “если”, “если”, “если”, “если”.

Основной код

1. Работа. php (который определяет интерфейс, необходимый программе time, и поддерживает экземпляр определенной роли состояния, делегируя операции, связанные с состоянием, текущему конкретному объекту.)

current = new EarlyMorning();  
    }
    // Setup status  
    public function SetState($s)  
    {
        $this->current = $s;  
    }  
  
    public function WriteCode()  
    { 
       return $this->current->WriteCode($this);  
    }  
}

2. IState.php (Определите интерфейс для инкапсуляции определенного поведения, связанного с состоянием, с использованием контекста.)

3. Раннее утро. php.

// Morning working status  
class EarlyMorning implements IState  
{ 
    public function WriteCode($w)  
    {  
        if($w->hour<6)  
        {  
           return Yii::t('yii','Good Early morning'); 
        }else{  
            $w->SetState(new GoodMorning());  
           Return $w - > WriteCode (); // Note: Return must be returned here, otherwise the client code cannot be assigned to $call.
        }   
           
    }  
} 

// Morning working status  
class GoodMorning implements IState  
{ 
    public function WriteCode($w)  
    {  
        if($w->hour<9)  
        {  
           return Yii::t('yii','Good morning'); 
        }else{  
            $w->SetState(new GoodForenoon());  
           return $w->WriteCode();  
        }    
    }  
} 

// Morning working status  
class GoodForenoon implements IState  
{ 
    public function WriteCode($w)  
    {   
        if($w->hour<12)  
        { 
           return Yii::t('yii','Good forenoon'); 
        }else{  
            $w->SetState(new GoodNoon());  
           return $w->WriteCode();  
        }    
    }  
} 

// Working state at noon  
class GoodNoon implements IState  
{ 
    public function WriteCode($w)  
    { 
        if($w->hour<14)  
        {  
           return Yii::t('yii','Good noon'); 
        }else{  
            $w->SetState(new GoodAfternoon());  
           return $w->WriteCode();  
        }    
    }  
} 

// Working state in the afternoon  
class GoodAfternoon implements IState  
{ 
    public function WriteCode($w)  
    {  
        if($w->hour<17)  
        {  
           return Yii::t('yii','Good afternoon'); 
        }else{  
            $w->SetState(new GoodDusk());  
           return $w->WriteCode();  
        }    
    }  
}

// Working state in the evening  
class GoodDusk implements IState  
{ 
    public function WriteCode($w)  
    { 
        if($w->hour<19)  
        {  
           return Yii::t('yii','Good dusk'); 
        }else{  
            $w->SetState(new GoodNight());  
           return $w->WriteCode();  
        }   
    }  
} 

// Working state at night  
class GoodNight implements IState  
{ 
    public function WriteCode($w)  
    {  
        if($w->hour<22)  
        {  
           return Yii::t('yii','Good night'); 
        }else{  
            $w->SetState(new GoodAtNight());  
           return $w->WriteCode();  
        }   
    }  
} 

// Working state at night  
class GoodAtNight implements IState  
{ 
    public function WriteCode($w)  
    {  
        return Yii::t('yii','Good at night');  
    }  
}

Код клиента вызова

hour = date("H");  
$call=$emergWork->WriteCode();

Увеличить состояние

1. Например, добавьте “полуночное состояние” в исходное приложение. 1.1. Добавьте суждение if к исходному классу рабочего состояния в ночное время и назовите рабочее состояние в полночь, когда оно соответствует требованиям.

hour<23)  
        {   
            return Yii::t('yii','Good at night');  
        }else{  
            $w->SetState(new Midnight());  
            return  $w->WriteCode();  
        }   
    }  
}

1.2. Добавьте новый класс полуночного рабочего состояния, который записывает поведение, которое необходимо выполнить.

Ну, легко ли добавить состояние? Расширение очень хорошо.

Осторожность

1. Должен вернуться $w – > WriteCode () в классе интерфейса состояния реализации. В противном случае при вызове клиентского кода он не может быть назначен $call, и он будет выводиться непосредственно эхом. 2. Класс объектов $w в методе Записи кода общедоступной функции ($w) класса интерфейса состояния реализации должен быть рабочим объектом, а не объектом текущего класса.

Резюме и анализ

1, преимущества 1.1. Шаблон состояния локализует поведение, связанное с определенным состоянием, и разделяет поведение разных состояний. 1.2. Весь код, связанный с состоянием, существует в конкретном состоянии, поэтому легко добавлять новые состояния и переходы, определяя новые подклассы. 1.3. Режим состояния уменьшает взаимозависимость, разделяя все виды логики перехода состояния на подклассы состояния. 2, недостатки 2.1. Вызывает более конкретные подклассы.

Сопутствующая информация

Режим состояния