PHP design pattern series-Strategy pattern 1. Pattern Definition
Similar situations are often encountered in software development. there are multiple algorithms or policies for implementing a function. we can select different algorithms or policies based on different environments or conditions to complete this function. Such as search and sorting. a common method is Hard Coding in a class. to provide multiple search algorithms, you can write these algorithms into a class, multiple methods are provided in this class. each method corresponds to a specific search algorithm. of course, these search algorithms can also be encapsulated in a unified method, through if... Else... Or case and other condition judgment statements for selection. Both of these methods can be called hard encoding. to add a new search algorithm, you need to modify the source code of the encapsulated algorithm class. replace the search algorithm, you also need to modify the client call code. A large number of search algorithms are encapsulated in this algorithm class. This type of code is complicated and difficult to maintain. If we include these policies on the client, this approach is not desirable, it will lead to a large client program and difficult to maintain, if there are a large number of available algorithms, the problem will become more serious.
How can we separate algorithms from objects so that they can change independently of customers who use them? To this end, we introduce the policy mode.
Strategy is also called the algorithm cluster mode. it defines different algorithm families and can be replaced with each other. This mode allows algorithm changes to be independent of algorithm customers.
Common use cases, such as object filtering, can be filtered by date or by ID. for example, in unit testing, we can switch between files and memory storage.
2. UML class diagram
3. sample code ObjectCollection. php
Elements = $ elements;}/*** @ return array */public function sort () {if (! $ This-> comparator) {throw new \ LogicException ("Comparator is not set");} $ callback = array ($ this-> comparator, 'compare '); uasort ($ this-> elements, $ callback); return $ this-> elements ;} /*** @ param ComparatorInterface $ comparator *** @ return void */public function setComparator (ComparatorInterface $ comparator) {$ this-> comparator = $ comparator ;}}
ComparatorInterface. php
DateComparator. php
IdComparator. php
4. test code Tests/StrategyTest. php
2), array ('id' => 1), array ('id' => 3), array ('id' => 1 )), array ('id' => 3), array ('id' => 2), array ('id' => 1 )), array ('id' => 1),);} public function getDateCollection () {return array ('date' => '2017-03-03 '), array ('date' => '2017-03-02 '), array ('date' => '2017-03-01 '), array ('date' => '2017-03-01 ')), array ('date' => '2017-02-03 '), array ('date' => '2017-02-01 '), array ('date' => '2014-02-02 '), array ('date' => '2014-02-01 ')),);} /*** @ dataProvider getIdCollection */public function testIdComparator ($ collection, $ expected) {$ obj = new ObjectCollection ($ collection ); $ obj-> setComparator (new IdComparator (); $ elements = $ obj-> sort (); $ firstElement = array_shift ($ elements ); $ this-> assertEquals ($ expected, $ firstElement);}/*** @ dataProvider getDateCollection */public function testDateComparator ($ collection, $ expected) {$ obj = new ObjectCollection ($ collection); $ obj-> setComparator (new DateComparator (); $ elements = $ obj-> sort (); $ firstElement = array_shift ($ elements); $ this-> assertEquals ($ expected, $ firstElement );}}
5. SummaryPolicy mode is an object behavior mode. it encapsulates an algorithm into an independent class with a common interface for mutual replacement. The policy mode allows the algorithm to change without affecting the client. Generally, the policy mode is applicable when an application needs to implement a specific service or function, and the program has multiple implementation methods.