1、模式定义
状态模式(State)又称状态对象模式,主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。状态模式允许一个对象在其内部状态改变的时候改变其行为,把状态的判断逻辑转移到表示不同的一系列类当中,从而把复杂的逻辑判断简单化。
用一句话来表述,状态模式把所研究的对象的行为包装在不同的状态对象里,每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的时候,其行为也随之改变。
2、UML类图
3、实例代码
OrderController.php
1 | <?phpnamespace DesignPatterns\Behavioral\State; class OrderController{ public function shipAction( $id ) { $order = OrderFactory::getOrder( $id ); try { $order ->shipOrder(); } catch (Exception $e ) {
|
Copier après la connexion
OrderFactory.php
1 | <?phpnamespace DesignPatterns\Behavioral\State; class OrderFactory{ private function __construct() { throw new \Exception( 'Can not instance the OrderFactory class!' ); } public static function getOrder( $id ) {
|
Copier après la connexion
OrderInterface.php
1 | <?phpnamespace DesignPatterns\Behavioral\State; interface OrderInterface{ public function shipOrder(); public function completeOrder();}
|
Copier après la connexion
ShippingOrder.php
1 | <?phpnamespace DesignPatterns\Behavioral\State; class ShippingOrder implements OrderInterface{ private $order ; public function __construct( array $order ) { if ( empty ( $order )) { throw new \Exception( 'Order can not be empty!' ); } $this ->order = $order ; } public function shipOrder() {
|
Copier après la connexion
CreateOrder.php
1 | <?phpnamespace DesignPatterns\Behavioral\State; class CreateOrder implements OrderInterface{ private $order ; public function __construct( array $order ) { if ( empty ( $order )) { throw new \Exception( 'Order can not be empty!' ); } $this ->order = $order ; } public function shipOrder() { $this ->order[ 'status' ] = 'shipping' ; $this ->order[ 'updatedTime' ] = time();
|
Copier après la connexion
注:由于代码中使用了伪代码,所以这里就不进行测试了。
4、总结
在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到。然后使用if… ellse语句来做状态判断来进行不同情况的处理。但是对复杂状态的判断就显得“力不从心了”。随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱。维护也会很麻烦。那么就要考虑使用状态模式。
状态模式的主要优点在于封装了转换规则,并枚举可能的状态,它将所有与某个状态有关的行为放到一个类中,并且可以方便地增加新的状态,只需要改变对象状态即可改变对象的行为,还可以让多个环境对象共享一个状态对象,从而减少系统中对象的个数;其缺点在于使用状态模式会增加系统类和对象的个数,且状态模式的结构与实现都较为复杂,如果使用不当将导致程序结构和代码的混乱,对于可以切换状态的状态模式不满足“开闭原则”的要求。