What is a policy mode
The policy pattern defines a series of algorithms, encapsulates each algorithm, and allows them to be replaced with each other. The policy pattern makes the algorithm independent of the customers who use it.
when to use policy mode1, multiple classes only differ in performance behavior, you can use the Strategy mode, at run time to dynamically select the specific behavior to execute. 2. Different strategies (algorithms) need to be used in different situations, or strategies may be implemented in other ways in the future. 3, the customer hides the specific strategy (algorithm) Implementation details, each other completely independent.differentiate policy mode and state design patternThe factors that change in the state mode are the state, maintaining an instance of the current state of the subclass (which defines the current state) the factors that change in the policy pattern are the algorithm, which is configured as a specific policy object, which is an encapsulated algorithm. In state mode, the implementation context contains a variable to hold the current state. This specific state provides methods that can be changed from the current state recorded in the context variable to another state. The context participant in the policy model does not record the currently used policy because, unlike changing states, the changed algorithm generally does not depend on the algorithm that is currently in use. Obviously, there are cases where you might want to use another algorithm before executing an algorithm. If you attempt to access data in a table, you need to insert data into the table first, but this does not prevent the algorithm from attempting to obtain data from an empty table. But in the state mode it is easy to see that a state can only enter certain states, and cannot be transferred to another State. Simple example This example uses multiple PHP trigger scripts that invoke different methods of the client, and the client then invokes the specific policy requested by the context. For each policy, the HTML file contains the corresponding form, The form data is passed through a PHP trigger script to the client's method. The client further passes the request through the context to a specific policy. A connection helper class consists of an interface and a class that can be used to connect aMySQL database.
client.php
<?phpclass client{public function InsertData () { $context = new Context (new DataEntry ()); $context->algorithm (); } Public Function FindData () { $context = new Context (new Searchdata ()); $context->algorithm (); } Public Function ShowAll () { $context = new Context (new Displaydata ()); $context->algorithm (); } Public Function Changedata () { $context = new Context (new UpdateData ()); $context->algorithm (); } Public Function Killer () { $context = new Context (new DeleteRecord ()); $context->algorithm (); }}
To trigger a method of different specific policies (encapsulated algorithms), HTML invokes one of the following PHP trigger scripts.
inserttrigger.php
<?phpfunction __autoload ($class _name) { include $class _name. '. php ';} $trigger = new Client (); $trigger->insertdata ();
displaytrigger.php
<?phpfunction __autoload ($class _name) { include $class _name. '. php ';} $trigger = new Client (); $trigger->showall ();
findtrigger.php
<?phpfunction __autoload ($class _name) { include $class _name. '. php ';} $trigger = new Client (); $trigger->finddata ();
updatetrigger.php
<?phpfunction __autoload ($class _name) { include $class _name. '. php ';} $trigger = new Client (); $trigger->changedata ();
killtrigger.php
<?phpfunction __autoload ($class _name) { include $class _name. '. php ';} $trigger = new Client (); $trigger->killer ();
Context classes and strategy interfaces in the state mode design, the context is equivalent to a "tracker" (track Keeper), which tracks the current state. In the policy design pattern, the context has a completely different function for separating the request from the specific policy, so that the policy and the request can work independently. This embodies a kind of loosening between the request and the consequence. At the same time, it facilitates the request from the client. The context is not an interface, However, it has an aggregation relationship with the strategy interface. "Gang of Four" specifies the following characteristics:
- Use a specific policy object to configure
- Maintaining a reference to a strategy object
- You can define an interface that allows Strategy to access its data.
in the context code below, you can see the above features:
context.php
<?phpclass context{ private $strategy; Public function __construct (istrategy $strategy) { $this->strategy = $strategy; } Public function algorithm () { $this->strategy->algorithm ();} }
For the above three features first, the constructor expects a istrategy implementation as a parameter. Second, a reference to the Strategy object is maintained through a encapsulated property $strategy (visibility is private). $ The Strategy property receives an Strategy object instance from the constructor parameter, which becomes a concrete policy instance.Thirdly, the algorithm () method realizes the IStrategy algorithm () method and realizes the specific strategy chosen by the client. Because context and istrategy form an aggregation relationship, Therefore, the context has some characteristics of an abstract class or interface. In fact, it is best to understand the context through aggregation. When viewing the policy interface IStrategy, you can see that the method to be implemented is algorithm ():
istrategy.php
<?phpinterface istrategy{public function algorithm ();}
The package algorithm family, which makes specific policies that make up the policy, provides all possible strategies. For this example, the key is to understand how different participants in the strategy design pattern work together. The specific strategies are as follows, which represent the typical algorithms used in conjunction with PHP and MySQL.
dataentry.php
<?phpclass DataEntry implements istrategy{public function algorithm () { $hookup = Universalconnect:: Doconnect (); $test = $hookup->real_escape_string ($_post[' data '); echo "The data has been entered:". $test. ' <br/> '; }}
displaydata.php
<?phpclass Display implements istrategy{public function algorithm () { $test = "Here is all the data"; echo $test. ' <br/> '; }}
searchdata.php
<?phpclass Searchdata implements istrategy{public function algorithm () { $hookup = Universalconnect::d oconnect (); $test = $hookup->real_escape_string ($_post[' data '); echo "This is the data you want to query:". $test. ' <br/> '; }}
updatedata.php
<?phpclass UpdateData implements istrategy{public function algorithm () { $hookup = Universalconnect:: Doconnect (); $test = $hookup->real_escape_string ($_post[' data '); echo "The new data is:". $test. ' <br/> '; }}
deletedata.php
<?phpclass DeleteData implements istrategy{public function algorithm () { $hookup = Universalconnect:: Doconnect (); $test = $hookup->real_escape_string ($_post[' data '); echo "This record:". $test. ' has been removed <br/> '; }}
increase data security and parameterization algorithms to extend the policy modelThe following example adds functionality to different strategies and adds an auxiliary class to handle the secure movement of data from the HTML client to the MySQL database. The client class can handle security on its own, but, in addition to making requests, Adds additional responsibility to the client class. Add a SecureData class to assist in creating a MySQL connection
securedata.php
<?phpclass securedata{Private $changeField; Private $company; Private $devdes; Private $device; Private $disappear; Private $field; Private $hookup; Private $lang; Private $newData; Private $oldData; Private $plat; Private $style; Private $term; Private $dataPack; Public Function Enterdata () {$this->hookup=universalconnect::d oconnect (); $this->company = $this->hookup->real_escape_string ($_post[' Company '); $this->devdes = $this->hookup->real_escape_string ($_post[' devdes '); $this->lang = $this->hookup->real_escape_string ($_post[' Lang '); $this->plat = $this->hookup->real_escape_string ($_post[' plat '); $this->style = $this->hookup->real_escape_string ($_post[' style '); $this->device = $this->hookup->real_escape_string ($_post[' device '); $this->datapack = Array ($this->company, $this->devdes, $this->lang, $this->plat, $this->style, $this->device); $this->hookup->close (); Public Function Conductsearch () {$this->hookup=universalconnect::d oconnect (); $this->field = $this->hookup->real_escape_string ($_post[' field '); $this->term = $this->hookup->real_escape_string ($_post[' term '); $this->datapack = Array ($this->field, $this->term); $this->hookup->close (); Public Function Makechange () {$this->hookup=universalconnect::d oconnect (); $this->changefield = $this->hookup->real_escape_string ($_post[' Update '); $this->olddata = $this->hookup->real_escape_string ($_post[' old '); $this->newdata = $this->hookup->real_escape_string ($_post[' new '); $this->datapack = Array ($this->changefield, $this->olDData, $this->newdata); $this->hookup->close (); Public Function RemoveRecord () {$this->hookup=universalconnect::d oconnect (); $this->disappear = $this->hookup->real_escape_string ($_post[' delete '); $this->datapack = Array ($this->disappear); $this->hookup->close (); } public Function Setentry () {return $this->datapack; }}
In addition to Setentry (), all methods generate an array named Datapack. The Setentry () method returns the current contents of this Datapack array. Depending on the specific request, the SecureData class generates the values that will be placed in the array. This is passed back to the client and sent to a specific policy as part of the request through the algorithm () method. Adding a parameter to an algorithm method the second feature to be added is to modify the strategy algorithm method. We will add an array as a parameter to the function, which can increase flexibility and handle more content. Each algorithm function call contains an array that contains the data passed from the HTML form:
istrategy.php
<?phpinterface istrategy{ Const TABLENOW = "survey"; Public function algorithm (Array $dataPack);}
Also, add a constant tablenow to the interface. Because each specific policy in this implementation uses the same table, PHP can pass constants through the interface. Therefore, a loosely coupled and reusable code can be created. Obviously, if you want to use different tables for different specific policies, you must specify the table references in each specific policy. The type hint in the argument is to use an array as an argument data input module that takes advantage of the SecureData helper class and the modified IStrategy interface (which can contain a parameter for the algorithm () method), for different HTML form requests, The client can make requests more easily based on the appropriate method. Customer Request Help
client.php
<?phpclass client{Public Function InsertData () {$secure = new SecureData (); $context = new Context (new DataEntry ()); $secure->enterdata (); $context->algorithm ($secure->setentry ()); Public Function FindData () {$secure = new SecureData (); $context = new Context (new Searchdata ()); $secure->conductsearch (); $context->algorithm ($secure->setentry ()); The Public Function ShowAll () {$dummy = array (0); $context = new Context (new Displaydata ()); $context->algorithm ($dummy); Public Function Changedata () {$secure = new SecureData (); $context = new Context (new UpdateData ()); $secure->makechange (); $context->algorithm ($secure->setentry ()); Public Function Killer () {$secure = new SecureData (); $context = new Context (new DeleteRecord ()); $secure->removerecord (); $context->algorithm(); }}
In addition to the ShowAll () method, all methods in the client instantiate the SecureData class first, and then use the concrete method as a parameter to create a context object. Next, The SecureData object invokes the appropriate method of the specific policy to create the required array. The last client method calls Context->algorithm () and returns $secure->setentry () using the SecureData class Array as an argument. The contents of the array depend on the user input that is sent by the HTML form and the type of policy requested. Context class important small changes the context class has almost no change, just adds a parameter to the algorithm () method, This is the request of the updated IStrategy interface. Because there is an aggregation relationship between the context class and the IStrategy, the context class must contain a reference to the istrategy. Similar to the previous example, create a context with a specific policy object .
context.php
<?phpclass context{ private $strategy; Private $dataPack; Public function __construct (istrategy $strategy) { $this->strategy = $strategy; } Public function algorithm (Array $dataPack) { $this->datapack = $dataPack; $this->strategy->algorithm ($this->datapack);} }
The fundamental purpose of a specific policy to pass data through an array to a specific policy is to allow different policies to respond to different requests. This provides flexibility for the design, because the array can be used to pass large amounts of data.
dataentry.php
<?phpclass DataEntry implements istrategy{private $tableMaster; Private $dataPack; Private $hookup; Private $sql; Public function algorithm (Array $dataPack) {$this->datapack = $dataPack; $comval = $this->datapack[0]; $devdesval = $this->datapack[1]; $langval = $this->datapack[2]; $platval = $this->datapack[3]; $cstyleval = $this->datapack[4]; $deviceval = $this->datapack[5]; $this->tablemaster = Istrategy::tablenow; $this->hookup = universalconnect::d oconnect (); $this->sql = "INSERT into $this->tablemaster (company, devdes, Lang, pla T, style, device) VALUES (' $comval ', ' $devdesval ', ' $l Angval ', ' $platval ', ' $cstyleval ', ' $deviceval '); if ($this->hookup->query ($this->sql)) {printf ("successfulInsert data into table: $this->tablemaster<br/> "); } else {printf ("Invalid sql:%s <br/> statement is:%s<br/>", $this->hookup->error, $this-&G T;SQL); Exit } $this->hookup->close (); }}
displaydata.php
<?phpclass Displaydata implements istrategy{private $tableMaster; Private $hookup; Public function algorithm (Array $dataPack) {$this->tablemaster = Istrategy::tablenow; $this->hookup = universalconnect::d oconnect (); $sql = "SELECT * from $this->tablemaster"; if ($result = $this->hookup->query ($sql)) {printf ("query returns%d records <br/>", $result->num_rows); echo "<table>"; while ($finfo = Mysqli_fetch_field ($result)) {echo "<th>{$finfo->name}</th>"; } while ($row = Mysqli_fetch_row ($result)) {echo "<tr>"; foreach ($row as $ceil) {echo "<td> $ceil </td>"; } echo "</tr>"; } echo "</table>"; $result->close (); } }}
searchdata.php
<?phpclass Searchdata implements istrategy{private $tableMaster; Private $dataPack; Private $hookup; Private $sql; Public function algorithm (Array $dataPack) {$this->tablemaster = Istrategy::tablenow; $this->hookup = universalconnect::d oconnect (); $this->datapack = $dataPack; $field = $this->datapack[0]; $term = $this->datapack[1]; $this->sql = "SELECT * from $this->tablemaster WHERE $field = ' $term '"; if ($result = $this->hookup->query ($this->sql)) {echo "<table>"; while ($finfo = Mysqli_fetch_field ($result)) {echo "<th>{$finfo->name}</th>"; } while ($row = Mysqli_fetch_row ($result)) {echo "<tr>"; foreach ($row as $ceil) {echo "<td> $ceil </td>"; } echo "</tr>"; } echo "</table>"; $result->close (); } $this->hookup->close (); }}
updatedata.php
<?phpclass UpdateData implements istrategy{ private $tableMaster; Private $dataPack; Private $hookup; Private $sql; Public function algorithm (Array $dataPack) { $this->tablemaster = Istrategy::tablenow; $this->hookup = universalconnect::d oconnect (); $this->datapack = $dataPack; $channelfield = $this->datapack[0]; $oldData = $this->datapack[1]; $newData = $this->datapack[2]; $this->sql = "UPDATE $this->tablemaster SET changefield= ' $newData ' WHERE changefield= ' $oldData '"; if ($result = $this->hookup->query ($this->sql)) { echo "$channelfield change from $oldData to $newData"; } Else { echo ' change Faield: '. $this->hookup->error; }}}
deletedata.php
<?phpclass DeleteData implements istrategy{ private $tableMaster; Private $dataPack; Private $hookup; Private $sql; Public function algorithm (Array $dataPack) { $this->tablemaster = Istrategy::tablenow; $this->hookup = universalconnect::d oconnect (); $this->datapack = $dataPack; $field = $this->datapack[0]; $term = $this->datapack[1]; $this->sql = "Select *from $this->tablemaster WHERE $field = ' $term '"; if ($result = $this->hookup->query ($this->sql)) { echo "table $this->tablemaster record has been deleted"; } else { echo ' delete failed '. $this->error; } }}
Flexible Policy ModelThe strategy model is flexible, changing the algorithm can only change one implementation, not only that, the schema itself can also have multiple implementations. On the one hand, it can invoke different algorithms. These algorithms are independent of data outside of specific policies, and on the other hand, you can pass secure data to specific policies.A particular policy pattern implementation relies on the needs of a particular algorithm and what it specifically needs. Some policy pattern implementations store a reference to their context, so there is no need to pass data. However, the context and strategy will be more tightly coupled.There is one more question to consider: the number of objects (specific policies) generated by the policy mode. In the example above, they all build a large number of objects (classes) to handle a simple MySQL request. It is also possible to build more objects. However, relative to reusability and the benefits of changing patterns, This may not be too much of a problem. The design pattern is built to increase the speed of an application, not to increase the speed at which code is executed. With a well-structured strategy model, developers can easily optimize and re-optimize the encapsulated algorithm without mess. So the speed surface is on reuse and modification time, and the overhead of extra objects is small.
Design Pattern: Policy mode