Every 5.1 and other festivals, you will see a sea of people in the mall. Malls are so attractive because of crazy discounts.
The following uses discounts for malls as an example to describe the strategic model.
Commodity discount algorithm:
Algorithm 1: There is no discount for some products.
Algorithm 2: Take a fixed discount for some commodities.
Algorithm 3: Take a discount on the percentage of some products.
Solution:
Solution 1: Put all the business logic on the client. The client selects a specific algorithm based on the parameters, but the client becomes complicated and difficult to maintain.
Solution 2: the client uses different levels of inheritance to implement different behaviors in sub-classes. However, the algorithm is closely coupled with the client.
Solution 3: Policy mode. Separate the policy algorithm from the client. In this way, the new discount algorithm does not need to be modified on the client.
Implementation of the Mode:
Class diagram:
Abstract discount class:
Abstract discount code:
Package Oliver. designpattern. Strategy; <br/> Abstract Public class discountstrategy <br/>{< br/>/** <br/> * unit price. <Br/> */<br/> protected double price = 0.0d; </P> <p>/** <br/> * number of items. <Br/> */<br/> protected int copies = 0; </P> <p>/** <br/> * <B> constructor. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * @ Param price <br/> * @ Param copies <br/> */<br/> Public discountstrategy (double price, int copies) <br/>{< br/> This. price = price; <br/> This. copies = copies; <br/>}</P> <p>/** <br/> * <B> Discount calculation. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * @ return <br/> */<br/> public abstract double calculatediscount (); <br/> Public double getprice () <br/>{< br/> return price; <br/>}< br/> Public void setprice (double price) <br/>{< br/> This. price = price; <br/>}< br/> Public int getcopies () <br/>{< br/> return copies; <br/>}< br/> Public void setcopies (INT copies) <br/>{< br/> This. copies = copies; <br/>}< br/>
No discount strategy:
No discount policy code:
Package Oliver. designpattern. Strategy; <br/>/** <br/> * <B> no discount policy. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:02:35 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> public class nodiscountstrategy extends discountstrategy <br/>{< br/> /* * <br/> * <B> constructor. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * @ Param price <br/> * @ Param copies <br/> */<br/> Public nodiscountstrategy (double price, int copies) <br/>{< br/> super (price, copies); <br/>}< br/>/** <br/> * <B> calculatediscount. </B> <br/> * @ see Oliver. designpattern. strategy. discountstrategy # calculatediscount () <br/> */<br/> @ override <br/> Public double calculatediscount () <br/> {<br/> return 0; <br/>}< br/>
Fixed discount policies:
Fixed discount policy code:
Package Oliver. designpattern. Strategy; <br/>/** <br/> * <B> fixed discount policy. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:05:14 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> public class flatratestrategy extends discountstrategy <br/>{< br/> /* * <br/> * fixed discount price. <Br/> */<br/> private double amount; <br/>/** <br/> * <B> constructor. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * @ Param price <br/> * @ Param copies <br/> * @ Param amount <br/> */<br/> Public flatratestrategy (double price, int copies, double amount) <br/>{< br/> super (price, copies); <br/> This. amount = amount; <br/>}< br/>/** <br/> * <B> calculatediscount. </B> <br/> * @ see Oliver. designpattern. strategy. discountstrategy # calculatediscount () <br/> */<br/> @ override <br/> Public double calculatediscount () <br/> {<br/> return amount * copies; <br/>}< br/> Public double getamount () <br/>{< br/> return amount; <br/>}< br/> Public void setamount (double amount) <br/>{< br/> This. amount = amount; <br/>}< br/>
Percentage discount strategy:
Percent discount policy code:
Package Oliver. designpattern. Strategy; <br/>/** <br/> * <B> percent discount policy. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:10:42 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> public class percentagestrategy extends discountstrategy <br/> {<br/> /* * <br/> * discount percentage. <Br/> */<br/> private double percent; <br/>/** <br/> * <B> constructor. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * @ Param price <br/> * @ Param copies <br/> * @ Param percent <br/> */<br/> Public percentagestrategy (double price, int copies, double percent) <br/>{< br/> super (price, copies); <br/> This. percent = percent; <br/>}< br/>/** <br/> * <B> calculatediscount. </B> <br/> * @ see Oliver. designpattern. strategy. discountstrategy # calculatediscount () <br/> */<br/> @ override <br/> Public double calculatediscount () <br/>{< br/> return price * copies * percent; <br/>}< br/> Public double getpercent () <br/>{< br/> return percent; <br/>}< br/> Public void setpercent (double percent) <br/>{< br/> This. percent = percent; <br/>}< br/>
Test code:
Commodities-books:
Package Oliver. designpattern. Strategy. product; <br/> Import Oliver. designpattern. Strategy. discountstrategy; <br/>/** <br/> * <B> books. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:15:30 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> public class book <br/>{< br/>/** <br/> * discount policy. <Br/> */<br/> private discountstrategy; <br/> Public discountstrategy getdiscountstrategy () <br/> {<br/> return discountstrategy; <br/>}< br/> Public void setdiscountstrategy (discountstrategy) <br/>{< br/> This. discountstrategy = discountstrategy; <br/>}< br/>
Commodities-fruits:
Package Oliver. designpattern. Strategy. product; <br/> Import Oliver. designpattern. Strategy. discountstrategy; <br/>/** <br/> * <B> fruits. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:17:13 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> Public Class fruit <br/> {<br/>/** <br/> * discount policy. <Br/> */<br/> private discountstrategy; <br/> Public discountstrategy getdiscountstrategy () <br/> {<br/> return discountstrategy; <br/>}< br/> Public void setdiscountstrategy (discountstrategy) <br/>{< br/> This. discountstrategy = discountstrategy; <br/>}< br/>
Commodities -- toys:
Package Oliver. designpattern. Strategy. product; <br/> Import Oliver. designpattern. Strategy. discountstrategy; <br/>/** <br/> * <B> toy. </B> <br/> * <p> <B> Description: </B> </P> <br/> * <! -- Add a detailed description here --> <br/> * none. <Br/> * <p> <B> modify the list: </B> </P> <br/> * <Table width = "100%" cellspacing = 1 cellpadding = 3 border = 1> <br/> * <tr bgcolor =" # ccccff "> <TD> NO. </TD> <TD> author </TD> <TD> modification date </TD> <TD> modification content </TD>/ tr> <br/> * <! -- Add the modification list here, for more information, see <br/> * <tr> <TD> 1 </TD> <TD> Oliver </TD> <TD> May 13,201 0 10:22:24 am </TD> <TD> creation type </TD> </tr> <br/> * </table> <br/> * @ version 1.0 <br /> * @ author Oliver <br/> * @ since 1.0 <br/> */<br/> public class toy <br/>{< br/>/** <br/> * discount policy. <Br/> */<br/> private discountstrategy; <br/> Public discountstrategy getdiscountstrategy () <br/> {<br/> return discountstrategy; <br/>}< br/> Public void setdiscountstrategy (discountstrategy) <br/>{< br/> This. discountstrategy = discountstrategy; <br/>}< br/>
Main class:
Package Oliver. designpattern. strategy. test; <br/> Import Oliver. designpattern. strategy. flatratestrategy; <br/> Import Oliver. designpattern. strategy. nodiscountstrategy; <br/> Import Oliver. designpattern. strategy. percentagestrategy; <br/> Import Oliver. designpattern. strategy. product. book; <br/> Import Oliver. designpattern. strategy. product. fruit; <br/> Import Oliver. designpattern. strategy. product. toy; <br/> public class supermarket <br/> {<br/> Public static void main (string [] ARGs) <br/>{</P> <p> book englishbook = New Book (); <br/> englishbook. setdiscountstrategy (New percentagestrategy (202.16d, 5, 0.2); <br/> fruit Apple = new fruit (); <br/> apple. setdiscountstrategy (New flatratestrategy (1.3, 30, 0.1); <br/> toy car = new toy (); <br/> Car. setdiscountstrategy (New nodiscountstrategy (50.0, 1); </P> <p> system. out. println ("englishboos discount:" + englishbook. getdiscountstrategy (). calculatediscount (); <br/> system. out. println ("Apple discount:" + apple. getdiscountstrategy (). calculatediscount (); <br/> system. out. println ("toy car discount:" + car. getdiscountstrategy (). calculatediscount (); </P> <p >}< br/>
Usage of policy mode:
(1) If there are many classes in a system, the only difference between them is their behavior, the policy mode allows an object to dynamically select a behavior among many behaviors.
(2) A system must dynamically select one of the centralized algorithms. These algorithms can be encapsulated into specific algorithms, which are all subclasses of an abstract algorithm class.
(3) The data used by an algorithm of a system cannot be known to the above clients. The policy mode can avoid unnecessary access to complicated and algorithm-only data on the client.
(4) If an object has many behaviors and the appropriate mode is not used, these behaviors must be implemented using multiple conditional selection statements. In this case, the lateral mode is used to transfer these actions to the corresponding specific policy class, so that you can avoid using multiple conditional selection statements that are difficult to maintain and reflect the object-oriented design concept.
Advantages of the Policy mode:
(1) provides methods to manage related algorithms.
(2) Avoid the use of multiple Condition Selection statements that are difficult to maintain.
(3) provides methods to replace the inheritance relationship.
Disadvantages of Rule mode:
(1) The client must know all the policy classes in advance and decide to use them.
(2) There are many strategies caused by the rule mode.
In addition, there are many examples of policy modes in the Java language: comparator, layoutmanager in AWT, and border in swing. If you are interested, you can study it.
Engineering instance download: http://cid-2c8a0dc7c1eb1d71.skydrive.live.com/self.aspx/soft/Design%20Pattern/Strategy.7z