ホームページ >バックエンド開発 >PHPチュートリアル >PHP デザイン パターン シリーズ -- ステート パターン (状態)
状態パターン (State) は、状態オブジェクト パターンとも呼ばれ、主に、オブジェクトの状態遷移を制御する条件式が過大な場合の状況を解決します。複雑な。状態パターンを使用すると、オブジェクトの内部状態が変化したときにオブジェクトの動作を変更できるようになり、状態判断ロジックをさまざまな表現を表す一連のクラスに転送することで、複雑な論理判断が簡素化されます。
一言で言えば、状態パターンは、研究対象のオブジェクトの動作をさまざまな状態オブジェクトにラップします。各状態オブジェクトは、抽象状態クラスのサブクラスに属します。状態パターンの目的は、オブジェクトの内部状態が変化したときにオブジェクトの動作を変更できるようにすることです。
<?phpnamespace DesignPatterns\Behavioral\State;/** * OrderController类 */class OrderController{ /** * @param int $id */ public function shipAction($id) { $order = OrderFactory::getOrder($id); try { $order->shipOrder(); } catch (Exception $e) { //处理错误! } // 发送响应到浏览器 } /** * @param int $id */ public function completeAction($id) { $order = OrderFactory::getOrder($id); try { $order->completeOrder(); } catch (Exception $e) { //处理错误! } // 发送响应到浏览器 }}
<?phpnamespace DesignPatterns\Behavioral\State;/** * OrderFactory类 */class OrderFactory{ private function __construct() { throw new \Exception('Can not instance the OrderFactory class!'); } /** * @param int $id * * @return CreateOrder|ShippingOrder * @throws \Exception */ public static function getOrder($id) { //从数据库获取订单伪代码 $order = 'Get Order From Database'; switch ($order['status']) { case 'created': return new CreateOrder($order); case 'shipping': return new ShippingOrder($order); default: throw new \Exception('Order status error!'); break; } }}
<?phpnamespace DesignPatterns\Behavioral\State;/** * OrderInterface接口 */interface OrderInterface{ /** * @return mixed */ public function shipOrder(); /** * @return mixed */ public function completeOrder();}
<?phpnamespace DesignPatterns\Behavioral\State;/** * ShippingOrder类 */class ShippingOrder implements OrderInterface{ /** * @var array */ private $order; /** * @param array $order * * @throws \Exception */ public function __construct(array $order) { if (empty($order)) { throw new \Exception('Order can not be empty!'); } $this->order = $order; } /** * @return mixed|void * @throws \Exception */ public function shipOrder() { //当订单发货过程中不能对该订单进行发货处理 throw new \Exception('Can not ship the order which status is shipping!'); } /** * @return mixed */ public function completeOrder() { $this->order['status'] = 'completed'; $this->order['updatedTime'] = time(); // 将订单状态保存到数据库 return $this->updateOrder($this->order); }}
<?phpnamespace DesignPatterns\Behavioral\State;/** * CreateOrder类 */class CreateOrder implements OrderInterface{ /** * @var array */ private $order; /** * @param array $order * * @throws \Exception */ public function __construct(array $order) { if (empty($order)) { throw new \Exception('Order can not be empty!'); } $this->order = $order; } /** * @return mixed */ public function shipOrder() { $this->order['status'] = 'shipping'; $this->order['updatedTime'] = time(); // 将订单状态保存到数据库 return $this->updateOrder($this->order); } /** * @return mixed|void * @throws \Exception */ public function completeOrder() { // 还未发货的订单不能设置为完成状态 throw new \Exception('Can not complete the order which status is created!'); }}
注: code では疑似コードが使用されているため、ここではテストされません。
ソフトウェア開発プロセスにおいて、アプリケーションは状況に応じて異なる処理を実行することがあります。最も簡単な解決策は、これらすべての事態を考慮に入れることです。次に、if... ellse ステートメントを使用してステータスを判断し、さまざまな状況に対処します。しかし、複雑な国家の判断は「力不足」のようだ。新しい状態の追加や状態の変更 (if else (または switch case) ステートメントの追加や変更) によって大きな変更が生じる可能性があるため、プログラムの可読性やスケーラビリティも非常に弱くなります。メンテナンスも面倒になる場合があります。次に、状態パターンの使用を検討します。
状態パターンの主な利点は、変換ルールをカプセル化し、特定の状態に関連するすべての動作をクラスにまとめ、必要なだけ新しい状態を簡単に追加できることです。オブジェクトの状態を変更してオブジェクトの動作を変更することもできます。また、複数の環境オブジェクトが状態オブジェクトを共有できるようにすることで、システム内のオブジェクトの数を減らすこともできます。その欠点は、状態モードを使用するとシステム クラスの数が増えることです。モードの構造と実装は比較的複雑です。不適切に使用すると、状態を切り替えることができるステート モードは「オープニングとステート」の要件を満たしません。クロージング原則」。