(3) PHP project application of design pattern (policy pattern: mall cash register system) 1 policy pattern description policy pattern defines a series of algorithms and encapsulates each algorithm, they can also be replaced with each other. The rule mode allows algorithms to change independently of customers who use it.
2 Mode composition 1) abstract policy role (Strategy ):
A policy class is usually implemented by an interface or abstract class.
2) specific policy roles (ConcreteStrategy ):
Related algorithms and behaviors are encapsulated.
3) environment role (Context ):
Hold a reference to the policy class and call it to the client.
3. mode: the core ideology and strategy mode is a method to define some column algorithms. From a conceptual point of view, all these algorithms perform the same job, but they only implement different implementations, it can call all algorithms in the same way, reducing the coupling between various algorithm classes and algorithm classes. The algorithm of the command mode is independent of each other, and the work of each command is different. However, the policy mode is doing the same job.
4 mode architecture
5 Program Architecture
1) Strategy)
// Define the interface and define the policy algorithm interface IStrategy {// Algorithm Method public function doFunction ();}
2) specific policy (ConcreteStrategy)
// Specific A policy class ConcreteStrategyA implements IStrategy {public function doFunction () {echo 'Algorithm A '; }}// specific B policy class ConcreteStrategyB implements IStrategy {public function doFunction () {echo 'Algorithm B '; }}// a specific C strategy class ConcreteStrategyC implements IStrategy {public function doFunction () {echo 'Algorithm C ';}}
3) Context)
// Environment class: maintain a Strategy application class Context {// policy private $ _ strategy = null; public function _ construct (IStrategy $ strategy) {$ this-> _ strategy = $ strategy;} public function doWork () {return $ this-> _ strategy-> doFunction ();}}
4) Client)
// Client class Client {public function main ($ data) {// Policy $ context = new Context (new ConcreteStrategyA (); $ context-> doWork (); // B policy $ context = new Context (new ConcreteStrategyB (); $ context-> doWork (); // C policy $ context = new Context (new ConcreteStrategyC ()); $ context-> doWork ();}}
6. project application
6.1 requirement description: a mall cash register system is implemented. goods can be charged normally, at a discount, and at a rebate (coming to the "big talk design model").
6.2 according to the requirement analysis, you can design the billing operation into an interface algorithm. The interface is used for normal charges, discounts, and rebates, and different policy algorithms are implemented. Then, design an environment class to maintain the instance of the policy.
6.3 design architecture diagram
6.4 program source code download http://download.csdn.net/detail/clevercode/8700009
6.5 program description
1) strategy. php
_ MoneyRebate = $ rebate;}/*** returns the normal amount ** @ param double $ money amount * @ return double amount */public function acceptCash ($ money) {return $ this-> _ moneyRebate * $ money;} // class ReturnStrategy implements ICashStrategy {// condition private $ _ moneyCondition = null; // private $ _ moneyReturn = null;/*** constructor ** @ param double $ moneyCondition return condition * @ return double $ moneyReturn return * @ return void */ Public function _ construct ($ moneyCondition, $ moneyReturn) {$ this-> _ moneyCondition = $ moneyCondition; $ this-> _ moneyReturn = $ moneyReturn ;} /*** return normal amount ** @ param double $ money amount * @ return double amount */public function acceptCash ($ money) {if (! Isset ($ this-> _ moneyCondition) |! Isset ($ this-> _ moneyReturn) | $ this-> _ moneyCondition = 0) {return $ money ;} return $ money-floor ($ money/$ this-> _ moneyCondition) * $ this-> _ moneyReturn ;}}
2) strategyPattern. php
SetCashStrategy ($ type);}/*** set a policy (mixed use of simple factory and policy mode) ** @ param string $ type * @ return void */public function setCashStrategy ($ type) {$ cs = null; switch ($ type) {// normal policy case 'normal': $ cs = new NormalStrategy (); break; // discount policy case 'rebate8': $ cs = new RebateStrategy (0.8); break; // return policy case 'return300to100': $ cs = new ReturnStrategy (300,100); break;} $ this-> _ strategy = $ cs;}/*** get the result ** @ Param double $ money amount * @ return double */public function getResult ($ money) {return $ this-> _ strategy-> acceptCash ($ money );} /*** get result ** @ param string $ type * @ param int $ num quantity * @ param double $ price unit price * @ return double */public function getResultAll ($ type, $ num, $ price) {$ this-> setCashStrategy ($ type); return $ this-> getResult ($ num * $ price );}} /** client class * separates the client and business logic as much as possible, reducing the client and business logic algorithms * Makes the business logic algorithm more portable */class Client {public function main () {$ total = 0; $ cashContext = new CashContext (); // quantity purchased $ numA = 10; // unit price $ priceA = 100; // obtain the result in policy mode $ totalA = $ cashContext-> getResultAll ('normal', $ numA, $ priceA); $ this-> display ('A', 'normal', $ numA, $ priceA, $ totalA); // quantity purchased $ numB = 5; // unit price $ priceB = 100; // get discount policy result $ totalB = $ cashContext-> getResultAll ('rebate8', $ numB, $ priceB); $ This-> display ('B', 'rebate8', $ numB, $ priceB, $ totalB); // quantity purchased $ numC = 10; // unit price $ priceC = 100; // return policy result $ totalC = $ cashContext-> getResultAll ('return300to100', $ numC, $ priceC); $ this-> display ('C', 'return300to100 ', $ numC, $ priceC, $ totalC );} /*** print ** @ param string $ name Product name * @ param string $ type * @ param int $ num quantity * @ param double $ price unit price * @ return double */ public function display ($ Name, $ type, $ num, $ price, $ total) {echo date ('Y-m-d H: I: s '). ", $ name, [$ type], num: $ num, price: $ price, total: $ total \ r \ n ";}} /*** program entry */function start () {$ client = new Client (); $ client-> main ();} start ();?>
3) in strategy. php and strategyPattern. php. If you need to expand more policies, you only need to inherit the billing interface to implement more classes. here we use it in combination with the simple factory mode. The program is clearer.
7. Summary 7.1 Advantages: 1. the policy mode provides methods for managing related algorithm families. The hierarchical structure of a policy class defines an algorithm or behavior family. Proper use of inheritance can transfer public code to the parent class to avoid repeated code.
2. the policy mode provides a way to replace the inheritance relationship. Inheritance can process multiple algorithms or actions. If the policy mode is not used, the environment class that uses algorithms or behaviors may have some subclasses. each subclass provides a different algorithm or behavior. However, in this way, the user of an algorithm or behavior is mixed with the algorithm or behavior itself. The logic that determines which algorithm to use or which behavior to take is mixed with the logic of the algorithm or behavior, so that it is impossible to evolve independently. Inheritance makes it impossible to dynamically change algorithms or behaviors.
3. use policy mode to avoid using multiple conditional transfer statements. Multiple transfer statements are not easy to maintain. they mix the logic of which algorithm or behavior is adopted with the logic of the algorithm or behavior and are all listed in a multiple transfer statement, it is more primitive and backward than the inheritance method.
7.2 Disadvantages: 1. the client must know all the policy classes and decide which one to use. This means that the client must understand the differences between these algorithms so that appropriate algorithm classes can be selected in a timely manner. In other words, the policy mode is only applicable when the client knows all the algorithms or actions.
2. the policy mode creates many policy classes. each specific policy class produces a new class. Sometimes you can save the environment-dependent status to the client and design the policy class to be shared so that the policy class instance can be used by different clients. In other words, you can use the metadata mode to reduce the number of objects.
Copyright:
1) original works are from the "CleverCode Blog". during reprinting, please note the following original addresses. Otherwise, you will be held legally liable for copyright.
2) original address: (This address must be specified for reprinting ).
3) You are welcome to pay attention to more highlights of my blog :.