Rule mode of the JavaScript version and rule of the javascript version

Source: Internet
Author: User

Rule mode of the JavaScript version and rule of the javascript version

As the saying goes, all roads go to Rome. In the American drama jailbreak, Michael Scofield, the main character, designed two escape paths. Both roads can reach the infirmary near the outer wall of the prison.

Similarly, in reality, there are many ways to reach the same destination. For example, if we want to travel somewhere, we can select a route based on the actual situation.

  • If you don't have time but don't care about money, you can choose to fly.
  • If you have no money, you can choose to take a bus or train.
  • If you are a little poorer, you can choose to ride a bicycle.


In program design, we often encounter similar situations. There are multiple options to implement a function. For example, you can select the zip algorithm or gzip Algorithm for a compressed file program.

These algorithms are flexible and can be replaced at will. This solution is the policy model described in this chapter.

Policy patterns are defined to define a series of algorithms, encapsulate them one by one, and make them replace each other.

Rule modes are widely used. This section describes how to calculate the year-end bonus.

The year-end awards of many companies are based on the salary base of employees and the performance at the end of the year. For example, A person with A performance of S has A salary of 4 times, A person with A performance of A has A salary of 3 times, and A person with A performance of B has A salary of 2 times. Suppose the finance department asks us to provide a piece of code to help them calculate the employee's year-end bonus.

1. Initial code implementation

You can writecalculateBonusTo calculate the bonus amount of each person. Apparently,calculateBonusTo work properly, the function must receive two parameters: the employee's salary and performance evaluation level. The Code is as follows:

Var calculateBonus = function (performanceLevel, salary) {if (performanceLevel = 's') {return salary * 4;} if (performanceLevel = 'A ') {return salary * 3;} if (performanceLevel = 'B') {return salary * 2 ;}}; calculateBonus ('B', 20000); // output: 40000 calculateBonus ('s ', 6000); // output: 24000

It can be found that this code is very simple, but there are obvious shortcomings.

  • calculateBonusA large number of functionsif-elseStatement, which must overwrite all logical branches.

  • calculateBonusThe function lacks elasticity. If a new performance level C is added, or you want to change the reward factor of performance S to 5, you must go deepcalculateBonusThe internal implementation of the function violates the open-closed principle.

  • The reusability of algorithms is poor. What if we need to reuse these algorithms in other places of the program? We only select copy and paste.

Therefore, we need to refactor this code.

2. Use composite functions to reconstruct code

Generally, the easiest way to think of is to use composite functions to reconstruct it. we encapsulate various algorithms into small functions. These small functions are well named, you can clearly know which algorithm it corresponds to, and they can also be reused elsewhere in the program. The Code is as follows:

Var performanceS = function (salary) {return salary * 4 ;}; var performanceA = function (salary) {return salary * 3 ;}; var performanceB = function (salary) {return salary * 2;}; var calculateBonus = function (performanceLevel, salary) {if (performanceLevel = 's') {return performanceS (salary );} if (performanceLevel = 'A') {return performanceA (salary);} if (performanceLevel = 'B') {return performanceB (salary );}}; calculateBonus ('A', 10000); // output: 30000

At present, our program has been improved, but this improvement is very limited, we still have not solved the most important problem:calculateBonusFunctions may become larger and larger, and lack flexibility when the system changes.

3. Use the policy mode to reconstruct the code

After thinking, we have come up with a better solution-using the policy pattern to refactor the code. Policy mode refers to defining a series of algorithms and encapsulating them one by one. Separating the unchanged and changing parts is the topic of each design pattern, and the policy pattern is no exception. The purpose of the policy pattern is to separate the use of the algorithm from the implementation of the algorithm.

In this example, the algorithm usage remains unchanged, and the calculated bonus amount is obtained based on an algorithm. The implementation of algorithms varies and changes, and each performance corresponds to different computing rules.

A policy-based program consists of at least two parts. The first part is a set of policies that encapsulate specific algorithms and are responsible for specific computing processes. The second part is the environment Context. The Context accepts the customer's request and then delegates the request to a certain strategy class. To do this, it means that the reference to a policy object must be maintained in Context.

Now we use the policy mode to refactor the above Code. The first version imitates the implementation in the traditional object-oriented language. First, we encapsulate the computing rules of each type of performance in the corresponding policy class:

var performanceS = function(){};performanceS.prototype.calculate = function( salary ){    return salary * 4;};var performanceA = function(){};performanceA.prototype.calculate = function( salary ){    return salary * 3;};var performanceB = function(){};performanceB.prototype.calculate = function( salary ){    return salary * 2;};

Next, define the bonus class.Bonus:

Var Bonus = function () {this. salary = null; // original salary this. strategy = null; // policy object corresponding to the performance level}; Bonus. prototype. setSalary = function (salary) {this. salary = salary; // set the employee's original salary}; Bonus. prototype. setStrategy = function (strategy) {this. strategy = strategy; // set the policy object corresponding to the employee performance level}; Bonus. prototype. getBonus = function () {// get the bonus amount return this. strategy. calculate (this. salary); // delegate the calculation bonus operation to the corresponding policy object };

Before completing the final code, let's review the ideas of the Policy Model:

Define a series of algorithms, encapsulate them one by one, and enable them to replace 1 with each other.

To be more detailed, we define a series of algorithms and encapsulate them into a strategy class. The algorithms are encapsulated in the internal methods of the strategy class. When a customer initiates a request to Context, Context always delegates the request to one of these policy objects for calculation.

1. "And make them replace each other", which is largely relative to static language. Because there is a type check mechanism in the static type language, each policy class needs to implement the same interface. They can be replaced only when their real types are hidden behind the interface. This is not a problem in the "type fuzzy" language of JavaScript, and any object can be replaced and used. Therefore, "can be replaced with each other" in JavaScript shows that they have the same purpose and intent.

Now let's complete the remaining code in this example. CreatebonusObject, andbonusSet raw data, such as the employee's original salary. Next, we will pass in a policy object for calculating the bonus.bonusObject. Whenbonus.getBonus()When calculating the prize,bonusThe object itself is not capable of computing, but the request is delegated to the previously saved policy object:

Var bonus = new Bonus (); bonus. setSalary (1, 10000); bonus. setStrategy (new CES (); // sets the console of the Policy object. log (bonus. getBonus (); // output: 40000 bonus. setStrategy (new performanceA (); // sets the console of the Policy object. log (bonus. getBonus (); // output: 30000

We have just reconstructed the computing year-end award code using the policy model. We can see that after restructuring the policy model, the Code becomes clearer and the responsibilities of each class become clearer. However, this Code is based on the traditional object-oriented language. In the next section, we will understand the rule Mode Implemented with JavaScript.

In section 5.1, let'sstrategyObjects are created from various policy classes, which simulate the implementation of some traditional object-oriented languages. In fact, in JavaScript, functions are also objects, so the simpler and more direct approach isstrategyDirectly defined as a function:

var strategies = {    "S": function( salary ){        return salary * 4;    },    "A": function( salary ){        return salary * 3;    },    "B": function( salary ){        return salary * 2;    }}; 

Similarly, Context is not requiredBonusClass, we still usecalculateBonusThe function acts as the Context to accept user requests. After transformation, the code structure becomes more concise:

Var strategies = {"S": function (salary) {return salary * 4 ;}, "A": function (salary) {return salary * 3 ;}, "B ": function (salary) {return salary * 2 ;}}; var calculateBonus = function (level, salary) {return strategies [level] (salary) ;}; console. log (calculateBonus ('s ', 20000); // output: 80000console. log (calculateBonus ('A', 10000); // output: 30000

In the following example of easing animation and form verification, we use policy objects in the form of this function.

This article is excerpted from JavaScript design patterns and development practices.

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.