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