Define: define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
I. Strategy Mode
The purpose of the rule mode is to encapsulate each algorithm into an independent class with a common interface for mutual replacement. The policy mode allows the algorithm to change without affecting the client.
Suppose we want to design a shopping cart CAT System for e-commerce websites selling books. The simplest case is to multiply the unit price of all goods by the quantity, but the actual situation must be more complicated than that. For example, this website may offer a one-dollar discount for all teaching materials and a 7% discount for comic books, there is a 3% discount for computer books other than teaching materials, and no discount for other books. Because of this complicated discount algorithm, the price calculation problem needs to be systematically solved.
The policy mode can be used to separate the behavior from the environment. The environment class is responsible for maintaining and querying behavior classes, and various algorithms are provided in the specific strategy class (concretestrategy. Because the algorithm and environment are independent, the increase, decrease, and modification of the algorithm will not affect the environment and the client. When a new promotion discount or an existing discount policy changes, you only need to implement a new strategy class and register it on the client. The policy mode is equivalent to "plug-in (Pluggable) algorithms ".
Ii. Structure of policy Mode
Policy mode is the packaging of algorithms. It separates the responsibility for using algorithms from the algorithms themselves and delegates them to different objects for management. Rule mode typically packs a series of algorithms into a series of policy classes and serves as a subclass of an abstract policy class. In one sentence, it is: "prepare a set of algorithms and encapsulate each algorithm so that they can be exchanged. "
Policy is also called the policy mode gof95 ]. The following is a schematic policy pattern structure:
This mode involves three roles:
- Context Role: Hold a reference to the strategy class.
- Abstract Policy (Strategy) Role: This is an abstract role, usually implemented by an interface or abstract class. This role provides all the interfaces required for specific policy classes.
- Concretestrategy: encapsulates related algorithms or actions.
Iii. Schematic source code Using system; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; </P> <p> namespace strategy_pattern <br/> {<br/> // "strategy" <br/> abstract class strategy <br/> {<br/>/ /methods <br/> Abstract Public void algorithminterface (); <br/>}</P> <p> // "concretestrategya" <br/> class concretestrategya: strategy <br/> {<br/> // methods <br/> override public void algorithminterface () <br/> {<br/> console. writeline ("called concretestrategya. algorithminterface () "); <br/>}</P> <p> //" concretestrategyb "<br/> class concretestrategyb: strategy <br/> {<br/> // methods <br/> override public void algorithminterface () <br/> {<br/> console. writeline ("called concretestrategyb. algorithminterface () "); <br/>}</P> <p> //" concretestrategyc "<br/> class concretestrategyc: strategy <br/> {<br/> // methods <br/> override public void algorithminterface () <br/> {<br/> console. writeline ("called concretestrategyc. algorithminterface ()"); <br/>}</P> <p>/"context" <br/> class context <br/>{< br/> // Fields <br/> strategy Strategy; </P> <p> // constructors <br/> public context (strategy Strategy) <br/> {<br/> This. strategy = strategy; <br/>}</P> <p> // methods <br/> Public void contextinterface () <br/>{< br/> strategy. algorithminterface (); <br/>}</P> <p>/**/<br/> /// <summary> <br/> // client Test <br/> // </Summary> <br/> public class client <br/> {<br/> Public static void main (string [] ARGs) <br/>{< br/> // three contexts following different strategies <br/> context c = new context (New concretestrategya (); <br/> C. contextinterface (); </P> <p> context d = new context (New concretestrategyb (); <br/> D. contextinterface (); </P> <p> context E = new context (New concretestrategyc (); <br/> E. contextinterface (); </P> <p> console. read (); <br/>}< br/>
4. When to use specific policy roles
When learning the policy model, students often ask the following question: why can't we see from the policy model which specific policy applies to which situation?
The answer is very simple, and the policy mode is not responsible for this decision. In other words, it is up to the client to decide under what circumstances to use specific policy roles. Policy mode only encapsulates algorithms and provides new algorithms to be inserted into existing systems, and the old algorithms are "retired" from the system. Policy mode does not determine when to use the algorithms.
V. An example of a practical application Policy Model
The following example uses the policy mode to encapsulate different sorting algorithms in sorting objects, so that the client can dynamically Replace the sorting policies (including quicksort, shellsort, and mergesort ).
Using system; <br/> using system. collections; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; </P> <p> namespace strategy_pattern <br/> {<br/> // "strategy" <br/> abstract class sortstrategy <br/> {<br/>/ /methods <br/> Abstract Public void sort (arraylist list ); <br/>}</P> <p> // "concretestrategy" <br/> class quicksort: sortstrategy <br/>{< br/> // methods <br/> Public override void sort (arraylist list) <br/>{< br/> list. sort (); // default is quicksort <br/> console. writeline ("quicksorted List"); <br/>}</P> <p> // "concretestrategy" <br/> class shellsort: sortstrategy <br/>{< br/> // methods <br/> Public override void sort (arraylist list) <br/>{< br/> // list. shellsort (); <br/> console. writeline ("shellsorted List"); <br/>}</P> <p> // "concretestrategy" <br/> class mergesort: sortstrategy <br/>{< br/> // methods <br/> Public override void sort (arraylist list) <br/>{< br/> // list. mergesort (); <br/> console. writeline ("mergesorted List "); <br/>}</P> <p> // "context" <br/> class sortedlist <br/>{< br/> // Fields <br/> private arraylist list = new arraylist (); <br/> private sortstrategy; </P> <p> // constructors <br/> Public void setsortstrategy (sortstrategy) <br/>{< br/> This. sortstrategy = sortstrategy; <br/>}</P> <p> // methods <br/> Public void sort () <br/>{< br/> sortstrategy. sort (list); <br/>}</P> <p> Public void add (string name) <br/>{< br/> list. add (name); <br/>}</P> <p> Public void display () <br/>{< br/> foreach (string name in List) <br/> console. writeline ("" + name ); <br/>}</P> <p>/**/<br/> /// <summary> <br/> // strategyapp Test <br/> // </Summary> <br/> public class strategyapp <br/> {<br/> Public static void main (string [] ARGs) <br/>{< br/> // two contexts following different strategies <br/> sortedlist studentrecords = new sortedlist (); <br/> studentrecords. add ("Samuel"); <br/> studentrecords. add ("Jimmy"); <br/> studentrecords. add ("Sandra"); <br/> studentrecords. add ("Anna"); <br/> studentrecords. add ("Vivek"); </P> <p> studentrecords. setsortstrategy (New quicksort (); <br/> studentrecords. sort (); <br/> studentrecords. display (); </P> <p> console. read (); <br/>}< br/>
6. Under what circumstances should I use the policy mode?
The policy mode should be considered in the following situations:
1. If there are many classes in a system, the difference between them is only their behavior, then the policy mode can dynamically allow an object to select a behavior among many behaviors.
2. A system must dynamically select one of several algorithms. These algorithms can be encapsulated into specific algorithm classes, which are subclasses of an abstract algorithm class. In other words, these specific algorithm classes have a unified interface. Due to the polymorphism principle, the client can choose to use any specific algorithm class and only hold one data type as the object of the abstract algorithm class.
3. The data used by a system algorithm cannot be known to the client. The policy mode prevents clients from involving complex and algorithm-only data that is not necessary for access.
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 policy mode is used to transfer these actions to the corresponding specific policy class, so that you can avoid using the multi-Condition Selection statements that are difficult to maintain and reflect the concept of object-oriented design.
VII. Advantages and disadvantages of the Policy Model
The rule mode has many advantages and disadvantages. It has the following 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 allows you to move public code to the parent class to avoid repeated code.
2. The rule 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.
Disadvantages of the Policy mode include:
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 rule mode causes many policy classes. 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.
8. Others
The rule mode is widely associated with many other models. Strategy is easily confused with the bridge mode. Although they have similar structures, they are designed to solve different problems. The Strategy Mode focuses on algorithm encapsulation, while the Bridge Mode focuses on separating abstraction and implementation, providing different implementations for an abstract system. Both the bridge and strategy modes reflect the viewpoint of "favor composite over inheritance.
We recommend that you read IOC container and dependency injection mode by Martin Fowler. You can find the Chinese PDF file on the Internet. It provides a very good solution for implementing the policy model.