Heim >Backend-Entwicklung >PHP-Tutorial >PHP-Entwurfsmuster: Verhaltensmuster (3)
7. Verantwortungskette:
Mehrere Objekte haben die Möglichkeit, Anfragen zu bearbeiten, wodurch der Sender und Empfänger der Anfrage entkoppelt werden. Genau wie an einem Geldautomaten in einer Bank können Sie an jedem Automaten Geld abheben.
Vorteile: Vereinfachte Struktur der versteckten Objektkette, was das Hinzufügen neuer Verantwortungsknoten erleichtert.
Nachteile: Die Anfrage hat möglicherweise keinen Empfänger oder wird von mehreren Empfängern aufgerufen, was zu einer verringerten Leistung führt.
Anwendungsszenario: Mehrere Anfragen bearbeiten.
Code-Implementierung:
<?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. Strategiemodus:
Definieren Sie eine Reihe von Algorithmen, kapseln Sie jeden Algorithmus und machen Sie sie austauschbar. Genau wie die Spieler einer Basketballmannschaft, auf und neben dem Platz. Der Trainer kann diejenigen, die auf dem Spielfeld sind, herunterkommen lassen, und er kann auch diejenigen, die nicht auf dem Spielfeld sind, spielen lassen.
Vorteile: Definieren Sie eine Reihe wiederverwendbarer Algorithmen und Verhaltensweisen und eliminieren Sie if else-Anweisungen.
Nachteil: Die aufrufende Seite muss alle Strategieklassen kennen.
Anwendungsszenario: Wird zum Ersetzen zwischen Objekten verwendet.
Code-Implementierung:
<?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();
Bekannte Modi
1. Memento-Modus (Memento):
Speichern Sie den Status des Objekts in einem Moment. Lieber, erinnerst du dich noch an seinen Klassenkameraden, der sagte: „Bitte ruf mich an, wenn der Lehrer kommt“?
Vorteile: Bietet Benutzern einen Mechanismus zum Wiederherstellen des Status.
Nachteile: Ressourcenverbrauch.
Anwendungsszenario: Wird für Daten verwendet, die gespeichert werden müssen.
Code-Implementierung:
<?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(); }
Deep-Modus
1. Dolmetschermodus (Interpreter):
Definieren Sie die Grammatik der Sprache und erstellen Sie eine Interpretation Die Maschine interpretiert Sätze in der Sprache. Das weiß jedes Kind, das schon einmal ein Wörterbuch benutzt hat.
Vorteile: Gute Skalierbarkeit und Flexibilität.
Nachteile: Komplexe Grammatiken können schwierig beizubehalten sein.
Anwendungsszenario: Paarweise oder Eins-zu-Viele-Anforderungen.
2. Besuchermodus (Besucher):
Kapselt bestimmte Operationen, die auf jedes Element in einer bestimmten Datenstruktur wirken. Sie können Operationen für jedes Element definieren, ohne die Datenstruktur zu ändern diese Elemente. Wie zum Beispiel Banknummeriermaschine.
Vorteile: Konzentrieren Sie verwandte Dinge in einem Besucherobjekt.
Nachteile: Das Hinzufügen neuer Datenstrukturen ist schwierig.
Anwendungsszenarien: Warteschlangen, Nummerierung.
3. Zusammenfassung
Verhaltensmuster betreffen die Verteilung von Verantwortlichkeiten zwischen Algorithmen und Objekten wird verwendet, um Verhaltensweisen zwischen Klassen zu verteilen. TemplateMethod und Interpreter sind Klassenverhaltensmuster. Verhaltensobjektmuster verwenden Objektzusammensetzung anstelle von Vererbung. Einige Verhaltensobjektmuster beschreiben, wie eine Gruppe von Peer-Objekten zusammenarbeitet, um Aufgaben zu erledigen, die kein einzelnes Objekt alleine erledigen kann, um die erforderliche Indirektheit bereitzustellen für lose Kopplung; Chain of Responsibility bietet implizit eine lose Anforderung an ein Objekt über eine Kandidatenobjektkette und kann bestimmen, welche Kandidaten zur Laufzeit an der Kette teilnehmen; Kapseln Sie häufig das Verhalten in einem Objekt und weisen Sie ihm Anforderungen zu, sodass Aspekte von einem Objekt geändert und spezifiziert werden können und kann in einer Verlaufsliste gespeichert oder auf andere Weise verwendet werden; der Zustandsmodus kapselt den Zustand eines Objekts, sodass das Objekt sein Verhalten ändern kann, das auf mehrere Klassen verteilt ist; Das Iterator-Muster abstrahiert die Art und Weise, auf Objekte in einer Sammlung zuzugreifen und diese zu durchlaufen.