7. 責任の連鎖:
複数のオブジェクトがリクエストを処理する機会があり、リクエストの送信者と受信者を分離します。銀行の現金自動預け払い機と同じように、どの機械からでもお金を引き出すことができます。
利点: オブジェクトの非表示チェーン構造が簡素化され、新しい責任ノードを簡単に追加できるようになります。
欠点: リクエストにレシーバーがないか、複数のレシーバーによって呼び出される可能性があり、その結果、パフォーマンスが低下します。
アプリケーションシナリオ: 複数のリクエストを処理します。
コード実装:
<?php /** * 优才网公开课示例代码 * * 职责链模式 Chain of Responsibility * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } /** * 加入在公司里,如果你的请假时间小于0.5天,那么只需要向leader打声招呼就OK了。 如果0.5<=请假天数<=3天,需要先leader打声招呼,然后部门经理签字。 如果3<请假天数,需要先leader打声招呼,然后到部门经理签字,最后总经经理确认签字, 如果请假天数超过10天,是任何人都不能批准的。 */ /** * 抽象处理者角色(Handler:Approver):定义一个处理请求的接口,和一个后继连接(可选) * */ abstract class Handler { protected $_handler = null; protected $_handlerName = null; public function setSuccessor($handler) { $this->_handler = $handler; } protected function _success($request) { output(sprintf("%s's request was passed", $request->getName())); return true; } abstract function handleRequest($request); } /** * 具体处理者角色(ConcreteHandler:President):处理它所负责的请求,可以访问后继者,如果可以处理请求则处理,否则将该请求转给他的后继者。 * */ class ConcreteHandlerLeader extends Handler { function __construct($handlerName){ $this->_handlerName = $handlerName; } public function handleRequest($request) { if($request->getDay() < 0.5) { output(sprintf('%s was told', $this->_handlerName)); // 已经跟leader招呼了 return $this->_success($request); } if ($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } } } /** * Manager * */ class ConcreteHandlerManager extends Handler { function __construct($handlerName){ $this->_handlerName = $handlerName; } public function handleRequest($request) { if(0.5 <= $request->getDay() && $request->getDay()<=3) { output(sprintf('%s signed', $this->_handlerName)); // 部门经理签字 return $this->_success($request); } if ($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } } } class ConcreteHandlerGeneralManager extends Handler { function __construct($handlerName){ $this->_handlerName = $handlerName; } public function handleRequest($request) { if(3 < $request->getDay() && $request->getDay() < 10){ output(sprintf('%s signed', $this->_handlerName)); // 总经理签字 return $this->_success($request); } if ($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } else { output(sprintf('no one can approve request more than 10 days')); } } } /** * 请假申请 * */ class Request { private $_name; private $_day; private $_reason; function __construct($name= '', $day= 0, $reason = ''){ $this->_name = $name; $this->_day = $day; $this->_reason = $reason; } public function setName($name){ $this->_name = $name; } public function getName(){ return $this->_name; } public function setDay($day){ $this->_day = $day; } public function getDay(){ return $this->_day ; } public function setReason($reason ){ $this->_reason = $reason; } public function getReason( ){ return $this->_reason; } } class Client { public static function test(){ $leader = new ConcreteHandlerLeader('leader'); $manager = new ConcreteHandlerManager('manager'); $generalManager = new ConcreteHandlerGeneralManager('generalManager'); //请求实例 $request = new Request('ucai',4,'休息'); $leader->setSuccessor($manager); $manager->setSuccessor($generalManager); $result = $leader->handleRequest($request); } } Client::test();
8. 戦略パターン:
一連のアルゴリズムを定義し、各アルゴリズムをカプセル化し、それらを交換可能にします。コートの内外でのバスケットボール チームの選手と同じです。コーチはフィールド上の選手を降ろさせることもできるし、フィールド外の選手をプレーさせることもできる。
利点: 一連の再利用可能なアルゴリズムと動作を定義し、if else ステートメントを排除します。
欠点: 呼び出し側はすべての戦略クラスを知っている必要があります。
アプリケーションシナリオ: オブジェクト間の置換に使用されます。
コード実装:
<?php /** * 优才网公开课示例代码 * * 策略模式 Strategy * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } //策略基类接口 interface IStrategy { public function OnTheWay(); } class WalkStrategy implements IStrategy { public function OnTheWay() { output( '在路上步行'); } } class RideBickStrategy implements IStrategy { public function OnTheWay() { output( '在路上骑自行车'); } } class CarStrategy implements IStrategy { public function OnTheWay() { output( '在路上开车'); } } //选择策略类Context class Context { public function find($strategy) { $strategy->OnTheWay(); } } class Client { public static function test(){ $travel = new Context(); $travel->find(new WalkStrategy()); $travel->find(new RideBickStrategy()); $travel->find(new CarStrategy()); } } Client::test();
既知のモード
1. Memento モード (Memento):
オブジェクトの状態を瞬間的に保存します。君、「先生が来たら電話してね」と言ってくれたデスクメイトをまだ覚えていますか?
利点: ユーザーにステータスを復元するメカニズムを提供します。
欠点: リソースの消費。
アプリケーションシナリオ: 保存する必要があるデータに使用されます。
コード実装:
<?php /** * 优才网公开课示例代码 * * 备忘录模式 Memento * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Originator { // 发起人(Originator)角色 private $_state; public function __construct() { $this->_state = ''; } public function createMemento() { // 创建备忘录 return new Memento($this->_state); } public function restoreMemento(Memento $memento) { // 将发起人恢复到备忘录对象记录的状态上 $this->_state = $memento->getState(); } public function setState($state) { $this->_state = $state; } public function getState() { return $this->_state; } public function showState() { output($this->_state); } } class Memento { // 备忘录(Memento)角色 private $_state; public function __construct($state) { $this->setState($state); } public function getState() { return $this->_state; } public function setState($state) { $this->_state = $state;} } class Caretaker { // 负责人(Caretaker)角色 private $_memento; public function getMemento() { return $this->_memento; } public function setMemento(Memento $memento) { $this->_memento = $memento; } } class Client { public static function test(){ $org = new Originator(); $org->setState('open'); $org->showState(); /* 创建备忘 */ $memento = $org->createMemento(); /* 通过Caretaker保存此备忘 */ $caretaker = new Caretaker(); $caretaker->setMemento($memento); /* 改变目标对象的状态 */ $org->setState('close'); $org->showState(); /* 还原操作 */ $org->restoreMemento($caretaker->getMemento()); $org->showState(); } } Client::test(); return; try { $db->beginTransaction(); $succ = $db->exec($sql_1); if (!$succ) { throw new Exception('SQL 1 update failed'); } $succ = $db->exec($sql_2); if (!$succ) { throw new Exception('SQL 2 update failed'); } $succ = $db->exec($sql_3); if (!$succ) { throw new Exception('SQL 3 update failed'); } $db->commit(); } catch (Exception $exp) { $db->rollBack(); }
ディープモード
1. インタープリターモード (インタープリター):
言語の文法を定義し、その言語の文を解釈するインタープリターを構築します。辞書を使ったことのある子供なら誰でもこのことを知っています。
利点: 優れた拡張性と柔軟性。
短所: 複雑な文法を維持するのが難しい場合があります。
アプリケーションシナリオ: ペアまたは 1 対多の要件に使用されます。
2. ビジター モード:
特定のデータ構造内の各要素に作用する特定の操作をカプセル化します。データ構造を変更せずに、これらの要素に作用する新しい操作を定義できます。銀行採番機など。
利点: 関連するものを訪問者オブジェクトに集中させます。
欠点: 新しいデータ構造を追加するのは困難です。
アプリケーションシナリオ: キューイング、ナンバリング。
3. 概要この記事では、動作パターンにはアルゴリズム間の割り当てが含まれており、動作クラス パターンはクラス間の動作を割り当てるために継承メカニズムを使用します。動作オブジェクト パターンでは、継承ではなくオブジェクトの構成を使用します。たとえば、Mediator は、必要な間接性を提供するために、ピア オブジェクトのグループが相互に連携してタスクを完了する方法を記述します。疎結合の場合、Chain of Responsibility はより疎な結合を提供し、実行時にどの候補がチェーンに参加するかを決定します。多くの場合、動作をオブジェクトにカプセル化し、それにリクエストを割り当てます。ストラテジ パターンはオブジェクト内にアルゴリズムをカプセル化し、オブジェクトによってアスペクトを変更および指定できるようにします。これにより、リクエストをパラメータとして渡すことができます。履歴リストに保存したり、他の方法で使用したりできます。状態モードはオブジェクトの状態をカプセル化するため、オブジェクトの状態オブジェクトが変化すると、そのオブジェクトの動作を複数のクラスに分散してカプセル化できます。 Iterator パターンは、コレクション内のオブジェクトにアクセスして横断する方法を抽象化します。