1. Parser mode//parser content class//for storing the result of the expression, and can return the results of the original record according to the passed expression class interpretercontext{private $expressionstore =array (); Put the object in an array, the index number is the object ID number function replace (Expression $exp, $value) {$this->expressionstore[$exp->getkey ()]= $value; The function lookup (Expression $exp) {return $this->expressionstore[$exp->getkey ()]; }}abstract class expression{private static $keyCount = 0; Private $key; Abstract function interpret (Interpretercontext $context); Each object has a unique key function GetKey () {if (!isset ($this->key)) {$this->key=++self:: $keyCount; } return $this->key; }}//String class Literalexpression extends expression{private $value; function __construct ($value) {$this->value= $value; } function interpret (Interpretercontext $context) {$context->replace ($this, $this->value); }}//variable class VariableExpression extends expression{private $value; Private $name; function __construct ($name, $value =null) {$this->name= $name; $this->value= $value; } function SetValue ($value) {$this->value= $value; } function GetKey () {return $this->name; } function interpret (Interpretercontext $context) {if (!is_null ($this->value)) {$context->replac E ($this, $this->value); is set to NULL, you can avoid calling the method again without modifying value, and//The second time the interpretercontext::replece $this->value=null; }}}//operator expression abstract class Operatorexpression extends expression{//left/right operand protected $l _op; protected $r _op; function __construct (Expression $l _op,expression $r _op) {$this->l_op= $l _op; $this->r_op= $r _op; } function interpret (Interpretercontext $context) {$this->l_op->interpret ($context); $this->r_op->interpret ($context); $result _l= $context->lookup ($this->l_op); $result _r= $context->lookup ($this->r_op); $this->dointerpret ($context, $result _l, $result _r); } protected abstract function Dointerpret (Interpretercontext $context, $result _l, $result _r);} The Equality expression class Equalsexpression extends operatorexpression{//The result is saved in this ... protected function Dointerpret (INTERPR Etercontext $context, $result _l, $result _r) {$context->replace ($this, $result _l== $result _r); }}//boolean or expression class Booleanorexpression extends operatorexpression{protected function Dointerpret (Interpretercontext $ Context, $result _l, $result _r) {$context->replace ($this, $result _l | | $result _r); }}//boolean and expression class Booleanandexpression extends operatorexpression{protected function Dointerpret (Interpretercontext $ Context, $result _l, $result _r) {$context->replace ($this, $result _l && $result _r); }}/* $context =new interpretercontext (), $literal =new literalexpression ("Bob"); $literal->interpret ($context); Print $context->lookup ($literal);//bob$context=new InterpretercOntext (); $myvar =new variableexpression ("V", "one"), $myvar->interpret ($context);p rint $context->lookup ($ MyVar),//one$myothervar=new variableexpression ("V"), $myvar->interpret ($context);p rint $context->lookup ($ MyVar)//one*///Use the code above to detect mini-languages//$input equals "4" or $input equals "four" $context =new Interpretercontext ();// A variable with no assignment $input=new variableexpression (' input ');//define a complex Boolean variable, initialize the parameters to be stored in the L_OP,R_OP//note, at this time they have not done the relevant operation, You must wait until the interpret ()//Of the Boolean variable is called, and the arguments inside the Boolean variable call their own interpret, forming a call stack ... $statement =new booleanorexpression (new Equalsexpression ($input, New Literalexpression (' Four ')), new Equalsexpression ($input, New Literalexpression (' 4 ')) ; $statement->interpret ($context);p rint $context->lookup ($statement); foreach (Array (' Four ', ' 4 ', ' * * ') as $val) {$input->setvalue ($val); print "$val: \ n"; $statement->interpret ($context); if ($context->lookup ($statement)) {print "Top marks\n"; }else{print "dunce hat on\n\n"; }}/*four:top mArks4:top marks52:dunce Hat on*/2. The policy model combines many different operations in a class with an algorithm from the same interface, which is encapsulated in a new class, and the main class is grouped or aggregated by the classification, and the//question class will be aggregated by marker into AB Stract class question{protected $prompt; protected $marker; function __construct ($prompt, Marker $marker) {$this->marker= $marker; $this->prompt= $prompt; }//using a delegate to implement function mark ($response) {return $this->marker->mark ($response); }}class Textquestion extends question{//handling text problem-specific operations}class Avquestion extends question{//handling speech problems-specific operations}//policy objects//The algorithm is partially independent Out encapsulated in the Marker class .... Abstract class marker{protected $test; function __construct ($test) {$this->test= $test; } Abstract function mark ($response);} MarkLogic language class Marklogicmarker extends marker{protected $engine; function __construct ($test) {parent::__construct ($test); } function mark ($response) {//Simulation returns true return true; }}//directly matches class Matchmarker extends marker{function mark ($response) {return ($this-> test== $response); }}//regular Expression class Regexpmarker extends marker{function mark ($response) {return (Preg_match ($this->test, $respon SE)); }}//Client Sample Code $markers=array (New Regexpmarker ("/f.ve/"), New Matchmarker ("Fivev"), New Marklogicmarker (' $input equals "five"); foreach ($markers as $marker) {print get_class ($marker). " \ n "; Create a new question and pass the marker instance in $question =new textquestion ("How many beans make five", $marker); foreach (Array ("Five", "four") as $response) {print "\ t response: $response:"; if ($question->mark ($response)) {print "Well done\n"; }else{print "Never mind\n"; }}}/*regexpmarker Response:five:well done response:four:never mindmatchmarker response:five:never Mind Response:four:never mindmarklogicmarker Response:five:well Done RESPONSE:FOUR:WELL DONE*/3 Observer pattern Observer pattern And Xing is to separate the customer element (the observer) from a central class. When an event occurs in the body, the observer must be notified! At the same time, the observer and the principal class are not implemented by hard coding, but rather through the interface combination aggregation implementation * Problem/Login Class (MasterBody Class) class Login {const LOGIN_USER_UNKNOWN = 1; Const LOGIN_WRONG_PASS = 2; Const LOGIN_ACCESS = 3; Private $status = Array (); Login operator Function Handlelogin ($user, $pass, $ip) {$ret =false; Switch (rand (1, 3)) {Case 1: $this->setstatus (self::login_access, $user, $IP); $ret =ture; Break Case 2: $this->setstatus (Self::login_wrong_pass, $user, $IP); $ret =false; Break Case 3: $this->setstatus (Self::login_user_unknown, $user, $IP); $ret =false; Break Default: $ret =false; }//If recording IP is required LOGGER::LOGIP ($user, $ip, $this->getstatus ()); If you need to send the IP of the person who failed the login to the admin mailbox ... if (! $ret) {notifier::mailwarning ($user, $ip, $this->getstatus ()); }//Need other features, such as special IP to set cookies ...//need to be added here ... return $ret; } function SetStatus ($status, $user, $ip) {$this->status = array ($status, $user, $IP); } function GetStatus () {return $this->status; }}class logger{static function Logip ($user, $ip, $status) {}}class notifier{static function mailwarning ($user, $ip, $st ATUs) {}}* uses the Observer pattern to make code changes less ...//abstract interface of the principal class interface observable{//additional function attach (Observer $observer); Delete function detach (Observer $observer); Notification function notify ();} Login Class (Principal Class) class login implements observable{const LOGIN_USER_UNKNOWN = 1; Const LOGIN_WRONG_PASS = 2; Const LOGIN_ACCESS = 3; Private $observers; Private $status = Array (); Login Operation function Handlelogin ($user, $pass, $ip) {$ret =false; Switch (rand (1, 3)) {Case 1: $this->setstatus (self::login_access, $user, $IP); $ret =ture; Break Case 2: $this->setstatus (self::Login_wrong_pass, $user, $IP); $ret =false; Break Case 3: $this->setstatus (Self::login_user_unknown, $user, $IP); $ret =false; Break Default: $ret =false; }//After using the Observer pattern, if you need to add new functionality, you just need to include the observer instance in this class ... $this->notify (); return $ret; } function SetStatus ($status, $user, $ip) {$this->status = array ($status, $user, $IP); } function GetStatus () {return $this->status; } function Attach (Observer $observer) {$this->observers[]= $observer; } function Detach (Observer $observer) {$newObserver =array (); foreach ($this->observers as $obs) {if ($obs!== $observer) {$newObserver []= $obs; }} $this->observers= $newObserver; }//Notify all observers function notify () {foreach ($this->observers as $bos) {$bos->update ($this); }}}//Observer interface interface observer{function update (Observable $observable);} Class Securitymonitor implements observer{function update (Observable $observable) {//getstatus () is not a Observable interface gauge The method $status = $observable->getstatus (); The judgment of status also involves the coupling problem if ($status [0]==login::login_wrong_pass] {//Send mail to Administrator print __class__. ": \ T sending mail to sysadmin\n "; }}} $login =new login (), $login->attach (New Securitymonitor ()), $login->handlelogin ("Coco", "123456", "127.0.0.1 ");//May output send message to admin * Improved viewer mode//observable element: base interface of Principal class Interface observable{//additional function attach (Observer $observer); Delete function detach (Observer $observer); Notification function notify ();} Login Class (Principal Class) class login implements observable{const LOGIN_USER_UNKNOWN = 1; Const LOGIN_WRONG_PASS = 2; Const LOGIN_ACCESS = 3; Private $observers; Private $status = Array (); Login Operation function Handlelogin ($user, $pass, $ip) {$ret =falsE Switch (rand (1, 3)) {Case 1: $this->setstatus (self::login_access, $user, $IP); $ret =ture; Break Case 2: $this->setstatus (Self::login_wrong_pass, $user, $IP); $ret =false; Break Case 3: $this->setstatus (Self::login_user_unknown, $user, $IP); $ret =false; Break Default: $ret =false; }//After using the Observer pattern, if you need to add new functionality, you just need to include the observer instance in this class ... $this->notify (); return $ret; } function SetStatus ($status, $user, $ip) {$this->status = array ($status, $user, $IP); } function GetStatus () {return $this->status; } function Attach (Observer $observer) {$this->observers[]= $observer; } function Detach (Observer $observer) {$newObserver =array (); foreach ($this->observers as $obs) {if ($obs!== $observer) {$newObserver []= $obs; }} $this->observers= $newObserver; }//Notify all observers function notify () {foreach ($this->observers as $bos) {$bos->update ($this); }}}//Observer interface interface observer{function update (Observable $observable);} LOGIN: Observer superclass (used to resolve the risk of invoking specific observable subclasses directly in Observer) abstract class Loginobserver implements observer{private $ Login function __construct (Login $login) {$this->login= $login; $this->login->attach ($this); }//This method triggers function update (Observable $observable) {/////When the method is invoked when certain methods of the subclass of Observable are called, the parameters passed in must be login valid ... if ($this->login=== $observable) {$this->doupdate ($observable); }} Abstract function DoUpdate (Login $login); }//the improved observer can guarantee that the observable instance method that is invoked must exist class Securitymonitor extends loginobserver{function doupdate (Login $login) { $status = $login->getstatus (); The judgment of status also involvesAnd to the coupling problem if ($status [0]==login::login_wrong_pass) {//Send mail to admin print __class__. ": \ T sending mail to sysadmin\n "; }}}//Daily Record class Generallogger extends loginobserver{function doupdate (Login $login) {$status = $login->gets Tatus (); Add record to log in//... print __class__. " \ t Add login data to log\n "; }}//Partner Tool Class Partnershiptool extends loginobserver{function doupdate (Login $login) {$status = $login->gets Tatus (); Check IP, if matching, set cookie ...//... print __class__. " \ t Set cookie if IP matches a list\n "; }}//client code changes a little bit ... $login =new login (); new Securitymonitor ($login); new Generallogger ($login); new Partnershiptool ($ login); $login->handlelogin ("Coco", "123456", "127.0.0.1");/* * May output *securitymonitor:sending mail to sysadmin *ge Nerallogger Add login data to log *partnershiptool set cookie if IP matches a list **/4. Visitor mode when working with object collections, we may need to apply various actions to each individual component of the structure. Such operations can be built into the component itself, after all, the groupIt is most convenient to call other components inside the piece. But this approach also has a problem because we don't know all the actions that might be required. If you add a new operation to the class with each additional operation, the class becomes more and more bloated. The visitor pattern can solve this problem.//This example is based on the code of "civilized" game ...// * Combat Unit Class abstract class unit{//depth protected $depth = 0; Attack intensity abstract function bombardstrength (); function Getcomposite () {return null; }//For the visitor pattern creation method function accept (Armyvisitor $visitor) {//Build a method name defined according to its own rules and then hand it to visitor itself $method = "Vis It ". Get_class ($this); $visitor-$method ($this); }//is used to calculate the depth of unit in the object Tree protected function setdepth ($depth) {$this->depth== $depth; } function Getdepth () {return $this->depth; }}//compound abstract class Compositeunit extends unit{protected $units =array (); Method for the visitor pattern function accept (Armyvisitor $visitor) {//Build a method name defined according to its own rules, and then hand over to visitor itself to call//First call to parent class accept (), and then Traversal call child element Accept () parent::accept ($visitor); foreach ($this->units as $thisunit) {$thisunit->accept ($visitor); }}//CanDo not write Bombardstrength () function Getcomposite () {return $this; }//Add unit//Tag node in the object tree in depth function addunit (unit $unit) {if (!empty ($unit)) {if (In_array ($unit, $ This->units,true)) {return; }//Can be replaced with the following code In_array () function//foreach ($this->units as $thisunit) {//if ($thisunit = = = $unit) {//return;//}//}//Calculate good depth first ... $unit->se Tdepth ($this->depth+1); Array_push ($this->units, $unit); }} function Removeunit (Unit $unit) {$this->units=array_udiff ($this->units, Array ($unit), function ($a, $b) {return ($a = = = $b? 0:1);}); }}//Shooter class Archer extends unit{function bombardstrength () {return 4; }}//Laser Tower class Lasercannonunit extends unit{function bombardstrength () {return 44; }}//Army: composed of combat units class Army extends compositeunit{//Calculate total strength function bombardstrength() {$ret = 0; foreach ($this->units as $unit) {$ret + = $unit->bombardstrength (); } return $ret; }//Mobile ability, defensive ability ... Omit}//Transport Troop: an army-like unit with 10 battle units, attack class Troopcarrier extends compositeunit{//have the same method and attribute function as the Army bombardstrengt H () {//do something ...}} Army Visitor base class abstract class armyvisitor{//related methods to be written later ...//army there may be a number of units, here are how many visit methods ...//method naming rules for visit+ class name//Default VI Sit abstract function visit (Unit $unit); function Visitarcher (Archer $node) {$this->visit ($node); } function Visitlasercannonunit (Lasercannonunit $node) {$this->visit ($node); } function Visitarmy (Army $node) {$this->visit ($node); } function Visittroopcarrier (Troopcarrier $node) {$this->visit ($node); }}//specific army visitor class, used to dump text class Textdumparmyvisitor extends armyvisitor{private $text = ""; function visit (Unit $node) {$ret = ""; $pad =4* $node->getdepth (); $ret. =sprintf ("%{$pad}s", "" "); $ret. =get_class ($node). ":"; $ret. = "Bombard:". $node->bombardstrength (). " \ n "; $this->text.= $ret; } function GetText () {return $this->text; }}//Client Instance Code $army=new Army (), $army->addunit (New Archer ()), $army->addunit (New Lasercannonunit ()); $textdump = New Textdumparmyvisitor (); $army->accept ($textdump);p rint $textdump->gettext (); */* army:bombard:48 * ARCHER:BO Mbard:4 * lasercannonunit:bombard:44 */5. Command mode//Command mode//Command mode is originally derived from graphical user interface design, but is now widely used in enterprise application design, especially facilitates the separation of controller (request and Division Processing)//and domain model (application logic). To make it easier, the command pattern helps the system organize better and is easy to expand The Command can be designed as an interface because it's simple ...//commands/command.phpabstract class command{abstract function Execute (commandcontext $ context);} Require_once ("command.php"); class registry{//An empty class ... static function Getaccessmanager () {return new Accessma Nager (); }}class accessmanager{Function Login () {return new StdClass (); } function GetError () {}}class Logincommand extends command{functioN Execute (commandcontext $context) {$manager =registry::getaccessmanager (); $user = $context->get (' username '); $user = $context->get (' Pass '); Fictitious empty space method $user _obj= $manager->login (); if (Is_null ($user _obj)) {$context->seterror ($manager->geterror ()); return false; } $context->addparam ("user", $user); return true; }} The//commandcontext class is used for task amplification, where the main function is to pass data to the command class class commandcontext{private $params =array (); Private $error = ""; function __construct () {$this->params=$_request; } function AddParam ($key, $val) {$this->params[$key]= $val; } function Get ($key) {return $this->params[$key]; } function SetError ($error) {$this->error= $error; } function GetError () {return $this->error; }}//client code (used to create commands) has caller code class Commandnotfoundexception extends exception{}//create command factory class commandfactory{private St Atic $dir= "Commands"; The corresponding $action+command class static function GetCommand ($action = ' default ') {//matches the occurrence of an illegal character (non-word) is dynamically created according to the parameter action, and the class file directory $dir Female digit underline) if (Preg_match ('/\w/', $action)) {throw new Exception ("Illegal characters in action"); } $class =ucfirst (Strtolower ($action). " Command "); $file =self:: $dir. Directory_separator. " {$class}.php "; if (!file_exists ($file)) {throw new Commandnotfoundexception ("file could not be find!"); } require_once ("$file"); if (!class_exists ($class)) {throw new Commandnotfoundexception ("class could not be find!"); } return new $class (); The}}//caller, which contains a Commandcontext object instance, is used to hold the data of the Web request class controller{private $context; function __construct () {$this->context=new commandcontext (); } function GetContext () {return $this->context; } function process () {$cmd =commandfactory::getcommand ($this->getcontext ()->get (' action ')); if (! $cmd->execute ($this->context)) {//Processing failed print "Faile in process!"; }else{//processing succeeds, the corresponding view layer print "Success in process!" can be displayed; }}} $controller =new controller (); $context = $controller->getcontext (); $context->addparam (' action ', ' Login '); $ Context->addparam (' user ', ' Cocos '), $context->addparam (' Pass ', ' Tiddles ');//controller execute the Process method, Need not understand the meaning of command. $controller->process ();//success in Process