preface
Delivery Address:
Front end design pattern factory pattern
Proxy patterns for front-end design patterns
Now that we’ve moved on to the third design pattern, following the agent pattern and the factory pattern, we continue with the link-policy pattern of the twenty-three design patterns.
The strategy pattern
Definition and characteristics of policy patterns
Definition of a Strategy pattern: This pattern defines a series of algorithms and encapsulates each algorithm so that they are interchangeable and changes to the algorithm do not affect the customers using the algorithm. The policy pattern belongs to the object behavior pattern. It encapsulates the algorithm, separates the responsibility of using the algorithm from the implementation of the algorithm, and assigns different objects to manage these algorithms. This description of the GOF design pattern is referenced in what is a policy pattern.
The main advantages of the policy pattern are as follows:
- Multi-conditional statements are difficult to maintain, and using policy patterns can avoid them.
- The policy pattern provides a family of algorithms that can be reused, and inheritance can be used appropriately to move the common code of the algorithm family into the parent class to avoid duplicate code.
- The policy pattern can provide different implementations of the same behavior, and customers can choose different ones based on different time or space requirements.
- The policy pattern provides perfect support for the open closed principle, allowing for the flexibility of adding new algorithms without modifying the original code.
- The policy pattern separates the use of the algorithm into the environment class and the implementation of the algorithm into the concrete policy class.
Its main disadvantages are as follows:
- The client must understand the differences between all the policy algorithms in order to select the right algorithm class at the right time.
- The policy pattern creates many policy classes.
A common understanding of the strategy pattern
In addition to recruiting agents for our pet store 🌰, we can also introduce big data analysis of the Internet to get the types of customers we recommend to improve service quality
The customer description | Pet is recommended | Pet pictures |
---|---|---|
Children customers: mainly recommend some of the more clever, not high aggression small dog | Shiba inu | |
Female customers: mainly recommend some small dogs with high appearance level | Samoya, chihuahua | |
First iron customers: mainly recommend some special toss, really warrior pet | husky |
🌰 above is a single condition, however in reality, a lot of things will be much more complex, such as customer will have across age, gender, lifestyle, family environment, personality and other factors mixed in a fast, so the user behavior portrait is a very complex and detailed things, also cause we are in the handling of customer preferences, there will be multiple conditions interference factors, The recommendation algorithm can be complicated.
The project of actual combat
Solve multi-conditional business
Order jump in multi-business scenarios is always a headache, because the order of each business may need customization and the details of the jump may be different. When there are too many business lines, it is easy to fall into the hell of multiple conditions and continuously add judgment conditions
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
if (orderType === 1) {
console.log('Beauty Order') // It is simple to use the printing method for example, in fact, it can be treated as each order condition jump, display operation is different
} else if (orderType === 2) {
console.log('Electrical Order')
} else if (orderType === 3) { console.log('Furniture Order') } Copy the code
As mentioned above, although it seems that there are many conditions, it belongs to a single condition. We can use the strategy mode to make simple transformation, as shown below:
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
const orderFunction = {
1() { console.log('Beauty Order')}, 2() { console.log('Electrical Order')}, 3() { console.log('Furniture Order')},} orderFunction[orderType]() Copy the code
Resolve multiple nested conditional services
But our business could be more complicated, order page, we adopted the h5 embedded in other applications, we may apply this business embedded quick, RN, a native App, small programs, such as environment, h5 display content and routing jump may be different, we in order to increase the difficulty and more intuitive, So each corresponding rule defaults to a completely different method.
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
const orderWay = 1 // 1: h5, 2: app, 3: applets
if (orderType === 1) {
if (orderWay === 1) {
console.log('Beauty Order H5') } else if (orderWay === 2) { console.log('Beauty Order App') } else if (orderWay === 3) { console.log('Beauty Order Mini Program') } } else if (orderType === 2) { if (orderWay === 1) { console.log('Electronics Order H5') } else if (orderWay === 2) { console.log('Electrical Appliance Order APP') } else if (orderWay === 3) { console.log('Electrical Order Mini-program') } } else if (orderType === 3) { if (orderWay === 1) { console.log('Furniture Order H5') } else if (orderWay === 2) { console.log('Furniture Order App') } else if (orderWay === 3) { console.log('Furniture Order Applet') } } Copy the code
When you look at the code above, you may be desperate because there are far more than three order types, far more than three environment types, and there may be many more attachment conditions that are not added. And as more and more conditions are added, the readability, maintainability and iterability of the code decrease rapidly, although the above code looks very neat after formatting.
Although the above conditions are multiple nested conditions, they can still be interpreted as a combination of order type and environment type. We use ES6 Map objects to transform them
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
const orderWay = 2 // 1: h5, 2: app, 3: applets
const strategy = (a)= > { // Order type + environment type policy
const map = new Map([
[{ orderType: 1. orderWay: 1 = > {}, () console.log('Beauty Order H5') }]. [{ orderType: 1. orderWay: 2 = > {}, () console.log('Beauty Order App') }]. [{ orderType: 1. orderWay: 3 = > {}, () console.log('Beauty Order Mini Program') }]. [{ orderType: 2. orderWay: 1 = > {}, () console.log('Electronics Order H5') }]. [{ orderType: 2. orderWay: 2 = > {}, () console.log('Electrical Appliance Order APP') }]. [{ orderType: 2. orderWay: 3 = > {}, () console.log('Electrical Order Mini-program') }]. [{ orderType: 3. orderWay: 1 = > {}, () console.log('Furniture Order H5') }]. [{ orderType: 3. orderWay: 2 = > {}, () console.log('Furniture Order App') }]. [{ orderType: 3. orderWay: 3 = > {}, () console.log('Furniture Order Applet') }]. ]) return map } const run = (orderType, orderWay) = > { let action = [...strategy()].filter(([key, value]) = > (key.orderType === orderType && key.orderWay === orderWay)) action.forEach(([key, value]) = > value.call(this)) } run(orderType, orderWay) Copy the code
As refactored above, we use the properties of map objects (we won’t go into any more details about map objects here). If there are new rules, we can add corresponding rules and methods in map to reduce the occurrence of conditional nesting hell, and the logic will be clearer. In practice, however, similar methods can be combined to make the logic clearer.
Solve multiple nested condition hell
The solution to the above multiple nested conditions is relatively simple, and it is difficult to have such a perfect condition judgment in reality. What is a view of hell
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
const orderWay = 1 // 1: h5, 2: app, 3: applets
const orderMoney = 100 // The amount range is divided into 0-100, 100-1000 and above 1000, and the details of the jump order are also different
if (orderType === 1) {
if (orderWay === 1) { if (0 <= orderMoney && orderMoney < 100) { console.log('Beauty Order H5-0') } else if (orderMoney < 1000) { console.log(Beauty Order H5-100) } else { console.log('Beauty Order H5-1000') } } else if (orderWay === 2) { if (0 <= orderMoney && orderMoney < 100) { console.log('Beauty Order APP-0') } else if (orderMoney < 1000) { console.log('Beauty Order APP-100') } else { console.log('Beauty Order APP-1000') } } else if (orderWay === 3) { if (0 <= orderMoney && orderMoney < 100) { console.log('Beauty Order Mini program -0') } else if (orderMoney < 1000) { console.log('Beauty Order Mini Program -100') } else { console.log('Beauty Order Mini Program -1000') } } } // There are too many conditions, so only one condition is used here Copy the code
Let’s briefly analyze the above conditions, and we can extract the same strategy. First, the combination of environment and order type can be known by default, so the amount criteria are extracted and returned as a set of policies
const orderType = 1 // 1: beauty makeup, 2: electrical appliances, 3: furniture
const orderWay = 1 // 1: h5, 2: app, 3: applets
const orderMoney = 10000 // The amount range is divided into 0-100, 100-1000 and above 1000, and the details of the jump order are also different
const orderMoneyStrategy = (orderMoney) = > { // Withdraw amount policy
if (0 <= orderMoney && orderMoney < 100) { return 1 } else if (orderMoney < 1000) { return 2 } return 3 } const strategy = (a)= > { // Order type + environment type policy const map = new Map([ [{ orderType: 1. orderWay: 1. orderMoney: 1 = > {}, () console.log('Beauty Order H5-0') }]. [{ orderType: 1. orderWay: 1. orderMoney: 2 = > {}, () console.log(Beauty Order H5-100) }]. [{ orderType: 1. orderWay: 1. orderMoney: 3 = > {}, () console.log('Beauty Order H5-1000') }]. ]) return map } const run = (orderType, orderWay, orderMoney) = > { let action = [...strategy()].filter(([key, value]) = > (key.orderType === orderType && key.orderWay === orderWay && key.orderMoney === orderMoney)) action.forEach(([key, value]) = > value.call(this)) } run(orderType, orderWay, orderMoneyStrategy(orderMoney)) Copy the code
The above is to separate and combine the two strategies, which can make the conditional logic clearer. However, it can also be seen from the above examples that the policy mode cannot reduce a lot of code in the use process, and the more strategies, the more complex the process of splitting and combining, so it should be used reasonably in the use process.
Additional information
Complete demo address: project actual combat demo, like friends can star, the follow-up will be based on the launch of the design mode blog, and gradually expand the project.
Manual doghead town building
This article is formatted using MDNICE