Design mode-Policy mode

Source: Internet
Author: User

Overview

In the policy mode, we can define some independent classes to encapsulate different algorithms, each of which encapsulates a specific algorithm, where each class of encapsulation algorithms can be called a strategy (strategy), in order to ensure consistency in the use of these policies, Typically, an abstract policy class is provided to define the rules, and each algorithm corresponds to a specific policy class.
The main purpose of the strategy mode is to separate the definition and use of the algorithm, that is, to separate the behavior and environment of the algorithm, and put the definition of the algorithm in a special policy class, each policy class encapsulates an implementation algorithm, and the environment class of the algorithm is programmed against the abstract policy class, which conforms to the "dependency reversal principle". When a new algorithm is presented, it is only necessary to add a new specific policy class that implements the abstract policy class.

Defined

Policy mode (strategy pattern): Defines a series of algorithm classes, encapsulates each algorithm, and allows them to be replaced by each other, and the policy pattern makes the algorithm independent of the customer using it, also known as policy mode. The policy mode is an object-based behavior pattern.

Structure of the policy pattern

The structure of the policy pattern is not complex, but we need to understand the context of the environment, which is structured in 24-1:

The following roles are included in the policy mode structure diagram:
Context (Environment Class): The Environment class is the role of the algorithm, which can be used to solve a problem (that is, implement a method) with a variety of strategies. Maintains a reference instance to an abstract policy class in the environment class that defines the policy being used.
Strategy (Abstract Policy Class): It declares abstract methods for the supported algorithms and is the parent class of all policy classes, which can be abstract or concrete or interfaces. The environment class invokes the algorithm implemented in the specific policy class at run time through the methods declared in the abstract policy class.
Concretestrategy (Specific policy Class): It implements the algorithm declared in the abstract policy class, at run time, the specific policy class will override the abstract policy class object defined in the Environment class, and use a specific algorithm to implement a business process.

The strategy pattern is a relatively easy to understand and use the design pattern, the strategy pattern is the encapsulation of the algorithm, it divides the responsibility of the algorithm and the algorithm itself, delegating to different object management. The policy pattern typically encapsulates a series of algorithms into a set of specific policy classes as subclasses of the abstract policy class. In policy mode, it is important to understand the environment classes and abstract policy classes, which are classes that require the use of algorithms. There can be multiple environment classes in a system, and they may need to reuse some of the same algorithms.
When using the policy mode, we need to extract the algorithm from the context class, and we should first create an abstract policy class whose typical code is as follows:

Typical code for a policy pattern
abstract class AbstractStrategy {    publicabstractvoidalgorithm//声明抽象算法}

The class that encapsulates each specific algorithm is then used as a subclass of the abstract policy class, as shown in the following code:

class ConcreteStrategyA extends AbstractStrategy {    //算法的具体实现    publicvoid algorithm() {       //算法A    }}

Similar to the other specific policy classes, for the context class, it establishes an association relationship between it and the abstract policy class, and its typical code is as follows:

class Context {  private//维持一个对抽象策略类的引用      publicvoidsetStrategy(AbstractStrategy strategy) {          this.strategy= strategy;      }      //调用策略类中的算法      publicvoidalgorithm() {          strategy.algorithm();      }  

Define an object of type Abstractstrategy in the context class strategy, by injecting a specific policy object into the client, the client code fragment is as follows:

……  ContextcontextnewContext();  AbstractStrategy strategy;  new ConcreteStrategyA(); //可在运行时指定类型  context.setStrategy(strategy);  context.algorithm();  

In the client code, just inject a specific policy object, you can store the specific policy class name in the configuration file, through reflection to dynamically create a specific policy object, so that users can flexibly change the specific policy classes, the addition of new specific policy classes is also convenient. The policy mode provides an implementation scheme of pluggable (pluggable) algorithm.

Instance Application

Software company for a cinema developed a set of cinema ticketing system, in the system needs to provide different types of users with different ways to discount movie tickets, the specific discount scheme is as follows:
(1) Students can enjoy 80 percent discount on their student ID card;
(2) Children aged 10 years and under can enjoy a discount of $10 per ticket (the original fare must be greater than or equal to 20 yuan);
(3) Cinema VIP users In addition to enjoy the price of half-price concessions can also be points, points accumulated to a certain amount can be exchanged for the prizes in the cinema.
In the future, the system may also need to introduce new discount methods as needed.

In order to realize the reuse of discount algorithm, and the flexibility to add new discounts to the system, the software company developers use the strategy model to reconstruct the movie theater discount scheme, after the reconstruction of the basic structure of 24-2 shows:

In Figure 24-2, Movieticket acts as an environment class role, discount acts as an abstract policy role, and Studentdiscount, Childrendiscount, and Vipdiscount act as specific policy roles. The complete code looks like this:

//Movie Ticket Category: Environment class class movieticket {    Private DoublePricePrivateDiscount Discount;//Maintain a reference to the abstract discount class     Public voidSetprice (DoublePrice) { This. Price = Price; }//Inject a discount class object     Public voidSetDiscount (Discount Discount) { This. Discount = discount; } Public DoubleGetPrice () {discount Price calculation method for Call discount class        returnDiscount.calculate ( This. Price); }}//Discount classes: Abstract policy classes interface Discount {     Public DoubleCalculateDoublePrice);}//Student Ticket discount Category: Specific strategy classes class studentdiscount implements Discount {     Public DoubleCalculateDoublePrice) {System.out.println ("Student Ticket:");returnPrice *0.8; }}//Child ticket Discount Category: Specific policy classes class childrendiscount implements Discount {     Public DoubleCalculateDoublePrice) {System.out.println ("Child ticket:");returnPrice-Ten; }}//VIP member Discount Category: Specific policy categories class vipdiscount implements Discount {     Public DoubleCalculateDoublePrice) {System.out.println ("VIP ticket:"); System.out.println ("Add points!" ");returnPrice *0.5; }}

To improve the flexibility and scalability of the system, we store the class name of the specific policy class in the configuration file, and use the tool class Xmlutil to read the configuration file and reflect the generated object, the code for the Xmlutil class looks like this:

 import javax.xml.parsers.*;   import org.w3c.dom.*;   import org.xml.sax.SAXException;   import java.io.*;   class xmlutil {  //This method is used to extract a specific class class name from an XML configuration file and return an instance object     Public StaticObject Getbean () {Try{//Create Document ObjectDocumentbuilderfactory dfactory = Documentbuilderfactory.newinstance ();              Documentbuilder builder = Dfactory.newdocumentbuilder ();                                         Document Doc; Doc = Builder.parse (NewFile ("config +"));//Gets the text node that contains the class nameNodeList nl = Doc.getelementsbytagname ("ClassName"); Node Classnode=nl.item (0). Getfirstchild (); String Cname=classnode.getnodevalue ();//Generate an instance object from the class name and return itClass C=class.forname (cName); Object obj=c.newinstance ();returnObj }Catch(Exception e) {E.printstacktrace ();return NULL; }      }  }

The class name for the specific policy class is stored in the config file, configuration, and the code is as follows:

<?xml version="1.0"?><config>    <className>StudentDiscount</className></config>

Write the following client test code:

Class Client { Public Static void Main(String args[]) {Movieticket MT =NewMovieticket ();DoubleOriginalPrice =60.0;DoubleCurrentprice;        Mt.setprice (OriginalPrice); System. out. println ("Original Price is:"+ OriginalPrice); System. out. println ("---------------------------------");        Discount Discount; Discount = (discount) xmlutil.getbean ();//Read configuration file and reflect generate specific discount objectMt.setdiscount (discount);//Inject Discount objectCurrentprice = Mt.getprice (); System. out. println ("Discounted price is:"+ Currentprice); }}

Compile and run the program with the following output:

原始价为:60.0---------------------------------学生票:折后价为:48.0

If you need to change the specific policy class, no need to modify the source code, just modify the configuration file, for example, to change the student ticket to a child ticket, simply change the specific policy class stored in the configuration file Studentdiscount to Childrendiscount, as shown in the following code:

<?xml version="1.0"?><config>    <className>ChildrenDiscount</className></config>

Rerun the client program with the following output:

原始价为:60.0---------------------------------儿童票:折后价为:50.0

If you need to add a new discount method, the original code is not modified, as long as a new discount class as a subclass of abstract discount class, to achieve the discount method declared in the abstract discount class, and then modify the configuration file, the original specific discount class name to the new discount class name can be fully in line with the "open and close principle."

Summarize

The policy mode is used for the free switching and expansion of the algorithm, which is one of the most widely used design patterns. The policy pattern corresponds to an algorithm family that solves a problem, allows the user to choose an algorithm from the algorithm family to solve a problem, and can easily replace the algorithm or add a new algorithm. You can consider using policy mode as long as the encapsulation, multiplexing, and switching of the algorithms are involved.

Advantages

The main advantages of the strategy model are as follows:
(1) The Strategy mode provides perfect support for the "open and close principle", the user can choose the algorithm or the behavior on the basis of not modifying the original system, also can add the new algorithm or behavior flexibly.
(2) The Strategy mode provides a way to manage the associated algorithm families. The hierarchy structure of a policy class defines an algorithm or a behavior family, and proper use of inheritance can move common code into abstract policy classes, thus avoiding duplicate code.
(3) The strategy model provides a way to replace the inheritance relationship. If the policy mode is not used, then the environment class using the algorithm may have some subclasses, each of which provides a different algorithm. However, the use of the algorithm is mixed with the algorithm itself, does not conform to the "single principle of responsibility", determines which algorithm to use the logic and the algorithm itself mixed together, so that it is impossible to evolve independently, and the use of inheritance can not implement the algorithm or behavior in the program runtime dynamic switch.
(4) Use the policy mode to avoid multiple conditional selection statements. Multiple conditional selection statements are difficult to maintain, and it mixes the logic of the algorithm or behavior with the implementation logic of the algorithm or the behavior itself, and hard-coding them all Coding in a large multi-conditional selection statement, which is more primitive and backward than the method of inheriting the environment class directly.
(5) The Strategy mode provides an algorithm reuse mechanism, because the algorithm is extracted separately and encapsulated in the policy class, so different environment classes can easily reuse these policy classes.

Disadvantages

The main disadvantages of the policy model are as follows:
(1) The client must know all of the policy classes and decide for itself which policy class to use. This means that the client must understand the differences between these algorithms in order to select the appropriate algorithm at the right time. In other words, the policy pattern applies only to situations where the client knows all the algorithms or behaviors.
(2) The strategy mode will cause the system to produce many specific policy classes, any small changes will cause the system to add a new concrete policy class.
(3) Multiple policy classes cannot be used at the client at the same time, that is, when the policy mode is used, the client can only use one policy class at a time, and it does not support the use of one policy class to complete some of the functionality before using another policy class to complete the remaining functionality.

Applicable scenarios

You can consider using the policy mode in the following situations:
(1) A system needs to be dynamically selected in several algorithms, then these algorithms can be encapsulated in a specific algorithm class, and these specific algorithm classes are a subclass of an abstract algorithm class. In other words, these specific algorithm classes have a unified interface, according to the "Richter substitution principle" and object-oriented polymorphism, the client can choose to use any specific algorithm class, and only need to maintain a data type is an abstract algorithm class object.
(2) An object has a lot of behavior, if not the appropriate pattern, these behaviors have to use multiple conditional selection statements to implement. In this case, using the policy mode, transfer these behaviors to the corresponding specific policy class, you can avoid the use of difficult to maintain multiple conditional selection statements.
(3) Do not want the client to know the complex, algorithm-related data structure, in the specific policy class encapsulation algorithm and related data structure, can improve the confidentiality and security of the algorithm.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Design mode-Policy mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.