Strategy Mode of grinding design mode-4

Source: Internet
Author: User
3.3 relationship between context and Strategy

In the policy mode, the context usually uses a specific policy to implement the object. In turn, the policy implementation object can also obtain the required data from the context, therefore, context can be passed to the policy implementation object. In this case, context and policy implementation objects are tightly coupled.
In this case, the context encapsulates specific policy objects. Algorithm The data required by the operation. The specific policy object obtains the data through the callback context method.
Even in some cases, policy implementation objects can call back context methods to implement certain functions. In this scenario, context serves as a public interface implemented by multiple policy algorithms in disguise, the context-defined method can be used as a public function for all or partial policy algorithms.
However, note that because all policy implementation objects implement the same policy interface and pass in the same context, the incoming context data may be wasted because some algorithms use the data, some algorithms are not used, but the overhead of interaction between context and Policy objects exists.
It can be illustrated through examples.
1. Implementation of wage payment
Consider this feature: many enterprises have flexible payment methods, and there are many payment options, such: RMB cash payment, USD cash payment, bank transfers to wage accounts, and bank transfers to payroll cards. Some entrepreneurial enterprises may also transfer wages to equity in order to retain key employees. In a word, there are many payment methods.
With the development of the company, there will be new payment methods, which requires convenient expansion. In addition, the payment method is not fixed and determined through negotiation between the company and its employees, that is to say, different employees may adopt different payment methods, or even the same employee may adopt different payment methods at different times, this requires that you can easily switch the specific payment method.
To implement such a function, the policy mode is a good choice. When implementing this function, different policy algorithms require different data. For example, a bank account is not required for cash payment, and an account is required for bank transfers. This leads to a poor decision on the number of parameters when designing methods in the policy interface. Even if all the parameters are listed now, what about future extension? Can I modify the policy interface again? If we do this, it would be a disaster. When we add a new policy, we need to modify the interface, and then modify all the existing implementations. It's not crazy! In the end, how can we achieve the most convenient expansion in the future?
One solution is to pass the context as a parameter to the policy object. In this way, to expand the new policy implementation, you only need to extend the context, existing implementations do not need to be modified.
Is this a good way to implement functions and have good scalability? Or pass Code For more information, see. Assume that two payment methods are implemented: RMB cash payment and USD cash payment. Then, the test is conducted, and then the bank transfer method to the payroll card is added, check whether it can be easily combined with existing implementations.

2: implementation code example
(1) first define the interface of the wage payment policy, that is, define a method to pay the wage. The sample code is as follows:

/**

* Interfaces for wage payment policies. The company has multiple wage payment algorithms.

* For example: cash, bank card, cash plus stock, cash plus option, USD payment, etc.

*/

Public interface paymentstrategy {

/**

* The company actually pays a salary for someone.

* @ Param CTX refers to the wage payment context, which contains the data required by the algorithm

*/

Public void pay (paymentcontext CTX );

}

(2) defines the interface for wage payment policies, so we should consider how to implement these multiple payment policies.
In order to make the demo simple, here we will first make a simple implementation of the RMB cash payment and USD cash payment methods, of course, it is not really to achieve the interaction with the bank, just give a look.
The example code is as follows:

/**

* RMB cash payment

*/

Public class rmbcash implements paymentstrategy {

Public void pay (paymentcontext CTX ){

System.Out. Println ("now to" + CTX. GetUserName ()

+ "RMB cash payment" + CTX. getmoney () + "RMB ");

}

}

The sample code is as follows:

/**

* USD in cash

*/

Public class dollarcash implements paymentstrategy {

Public void pay (paymentcontext CTX ){

System.Out. Println ("now to" + CTX. GetUserName ()

+ "USD cash payment" + CTX. getmoney () + "RMB ");

}

}

 

(3) Let's see the implementation of the payment context. Of course, the context of the payment policy needs to know which payment policy to use, generally, the client determines which specific policy is used and the context is responsible for actual execution. Therefore, this context requires a payment policy and is configured by the client. The sample code is as follows:

/**

* The context of pay-as-you-go. The payment method varies depending on the individual's salary.

*/

Public class paymentcontext {

/**

* Persons whose salaries should be paid should be replaced by their names simply.

*/

Private string username = NULL;

/**

* Amount of wages to be paid

*/

Private double currency = 0.0;

/**

* Interface of the wage payment method Policy

*/

Private paymentstrategy strategy = NULL;

/**

* Constructor: the amount to be paid and the specific payment policy of the person to be paid

* @ Param Username: the person who is paid the salary

* @ Param money the amount to be paid

* @ Param strategy specific payment policy

*/

Public paymentcontext (string username, double money,

Paymentstrategy Strategy ){

This. Username = username;

This. Money = money;

This. Strategy = strategy;

}

Public String GetUserName (){

Return username;

}

Public double getmoney (){

Return money;

}

/**

* Pay now

*/

PublicVoid paynow (){

//Use the customer's desired payment policy to pay the salary

This. Strategy. Pay (this );

}

}

 

(4) prepare various wage payment policies. Let's take a look at how to use these policies to actually pay wages. The client uses context to use specific policies, in addition, the client determines the specific policy, that is, the policy created by the client, which is finally run, and each policy can be dynamically switched. The sample code is as follows:

Public class client {

Public static void main (string [] ARGs ){

// Create a payment policy

Paymentstrategy strategyrmb = new rmbcash ();

Paymentstrategy strategydollar = new dollarcash ();

// Prepare Xiao Li's salary payment context

Paymentcontext ctx1 =

New paymentcontext ("Xiao Li", 5000, strategyrmb );

// Pay Xiao Li's salary

Ctx1.paynow ();

// Switch one person to pay the Petter's salary

Paymentcontext ctx2 =

New paymentcontext ("Petter", 8000, strategydollar );

Ctx2.paynow ();

}

}

 

Run the command to check the effect. The running result is as follows:

Now I am paying Xiao Li RMB 5000.0 in cash

$8000.0 in cash for Petter

 

3: Extension example, implementation method 1
The above test shows that two payment methods have been implemented by using the Policy mode. If you want to add a payment method that requires you to pay for your bank card, how can you easily expand it?
Add a new payment policy to the bank card, extend the payment context through inheritance, and add new data required for the new payment method, such as the bank card account, then, use the new context and new policy on the client to implement it. In this way, existing implementations do not need to be changed and fully follow the open-closed principle.
First, let's look at the implementation of the extended payment context object. The sample code is as follows:

/**

* Extended payment context object

*/

PublicClass paymentcontext2 ExtendsPaymentcontext{

/**

* Bank account

*/

Private string account = NULL;

/**

* Constructor: the amount to be paid and the specific payment policy of the person to be paid

* @ Param Username: the person who is paid the salary

* @ Param money the amount to be paid

* @ Param account: the bank account to which the payment is made

* @ Param strategy specific payment policy

*/

PublicPaymentcontext2 (string username, double money,

String account, paymentstrategy Strategy ){

Super (username, money, Strategy );

This. Account = Account;

}

Public String getaccount (){

Return account;

}

}

 

Then let's take a look at the implementation of the new policy algorithm. The sample code is as follows:

/**

* Payment to bank card

*/

Public class card implements paymentstrategy {

PublicVoid pay (paymentcontext CTX ){

//This new algorithm knows that it needs to use an extended payment context.

Paymentcontext2 ctx2 = (paymentcontext2) CTX;

System.Out. Println ("Now"+ Ctx2.getusername () +"Of"

+ Ctx2.getaccount () +"The account has paid"+ Ctx2.getmoney () +"RMB");

//Connect to the bank and transfer funds.

}

}

 

Finally, let's see how the client uses this new policy? The original code remains unchanged. Simply add a new test. The sample code is as follows:

Public class client {

Public static void main (string [] ARGs ){

// Create a payment policy

Paymentstrategy strategyrmb = new rmbcash ();

Paymentstrategy strategydollar = new dollarcash ();

// Prepare Xiao Li's salary payment context

Paymentcontext ctx1 =

New paymentcontext ("Xiao Li", 5000, strategyrmb );

// Pay Xiao Li's salary

Ctx1.paynow ();

// Switch one person to pay the Petter's salary

Paymentcontext ctx2 =

New paymentcontext ("Petter", 8000, strategydollar );

Ctx2.paynow ();

//Test the newly added payment method

Paymentstrategy strategycard = new card ();

Paymentcontext ctx3 = new paymentcontext2 (

"John", 9000, "010998877656", strategycard );

Ctx3.paynow ();

}

}

 

Test again and try again. The running result is as follows:

Now I am paying Xiao Li RMB 5000.0 in cash

$8000.0 in cash for Petter

Now I have paid 010998877656 yuan to John's 9000.0 account.

 

4: Extension example, implementation method 2
The above function is also implemented: Now you need to add a payment method that requires you to pay for your bank card.
(1) The above implementation is to prepare the data required by the new algorithm by extending the context object. Another way is to input the data required by the new algorithm through the Policy constructor. In this way, you do not need to extend the context. Simply add a new policy algorithm to implement it. The sample code is as follows:

/**

* Payment to bank card

*/

Public class card2 implements paymentstrategy {

/**

* Account information

*/

Private string account = "";

/**

* Constructor: Input account information

* @ Param account Account Information

*/

PublicCard2 (string account ){

This. Account = Account;

}

PublicVoid pay (paymentcontext CTX ){

System.Out. Println ("Now"+ CTX. GetUserName () +"Of"

+ This. Account +"The account has paid"+ CTX. getmoney () +"RMB");

//Connect to the bank and transfer funds.

}

}

 

(2) You can test it directly on the client. The test sample code is as follows:

Public class client {

Public static void main (string [] ARGs ){

// Test the newly added payment method

Paymentstrategy strategycard2 = new card2 ("010998877656 ");

Paymentcontext ctx4 =

New paymentcontext ("Xiao Zhang", 9000, strategycard2 );

Ctx4.paynow ();

}

}

 

Run and have a good experience.

(3) which of the following two extension implementation methods can be used? Or what kind of implementation is better? The following is a comparison:
Extended Context: In this way, the Implementation styles of all policies are more unified, and the data required by the policies are obtained from the context in a unified way. In addition, new data is added to the context, other algorithms can also be used as public data. However, the disadvantage is also obvious. If the data is used only by a specific algorithm, the data is a waste. In addition, every time a new algorithm is added, the context is extended, it is easy to form complex context object layers and is not necessary.
How to add the required data to the implementation of policy Algorithms: This is easy to implement. However, the disadvantage is also obvious. It is different from the style implemented by other policies. Other policies retrieve data from the context. However, some data of this policy comes from the context and some data comes from the context, some are not uniform. In this way, the external use of these policy algorithms is different, and it is not good to dynamically switch the policy Algorithm in a unified way.
The two implementations have their own advantages and disadvantages. As for how to choose them, the specific problems are analyzed.

5: Call Sequence of another policy Mode
There is another case for calling the rule mode, that is, to pass the context as a parameter to strategy, that is, this method is demonstrated in this example. In this case, the sequence of calling the rule mode is 4:
 

Figure 4 sequence 2 of policy mode calls

 

 

 

To be continued ......

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.