This is the 28th day of my participation in the August Text Challenge.More challenges in August

Design mode is the classical solution of some classical scenes summarized by predecessors. The core is an idea, not a language.

This explanation of the use case has been in place, I will not post my project JS example code

What is state mode

In our programs, there’s often a situation where we have to choose what to do based on the state that’s coming in from the outside, and that choice is scattered all over the code, and every time we choose it, it’s not necessarily the same type of thing to do, that is, it’s not directly a public function that’s coming in from the outside, right

Code demo

Classic scenes reappear

function out(type){
    // ...
    switch (type){
      case 1:
        // do first like this
        break;
      case 2:
        // do first like that
        break;
      // ...
    }
    / /...
    switch (type){
      case 1:
        // do second like this
        break;
      case 2:
        // do second like that
        break;
      // ...
    }
    / /...
}
Copy the code

Because it involves state, switch case or if else if need to be used for each processing. Besides, the actual processing function after selecting a condition will definitely not be a light line like DO XXX. These codes are nested in our normal business processing. It can also be wrapped into function calls, but management and maintenance are a big problem

Code optimization V1

Perhaps we could pull the code out of the case and use the function naming convention, something like this

function() doFirst_1(){}
function() doFirst_2(){}
/ /...
Copy the code

Optimize v2 again

We can also improve on the code from the previous step by using the closure idea to bring together the state-related code

let doThings = function(){
  return {
    type_1: {
      first(){},
      second(){},},type_2: {
      first(){},
      second(){},},/ /...
  }
}();
Copy the code

We then call the method in case in a manner similar to dothings.type_1.first ()

V1-1

Or is this optimization wrong and we just package the whole switch?

function first(type){
  switch (type){
    case 1:
      // do first like this
      break;
    	// ...}}Copy the code

Ugly code is just hiding in a different place

Apply design pattern V3

Conclusion first, this situation is very consistent with the state mode, we maintain the corresponding method according to the state

V2 already had this prototype, but did not handle the switch, so we directly encapsulated the state selection inside the function and provided methods to support state switching

Ideas:

  1. Define an object for each state, and implement corresponding methods in this object according to the state
  2. Maintain a state mapping to the object defined in the first step, because some state definitions may not be0, 1, 2...
  3. Define an internal state variable
  4. Declare a method that supports external changes to this state
  5. Expose an instance for external calls that correspond to externally specified states
let doThings = function(){
  let type_1 = {	/ / (1)
      first(){},
      second(){},
    }, type_2 = {
      first(){},
      second(){}};let status = {	/ / (2)
    0: type_1,
    1: type_2,
  }
  let innerType = 0;	/ / (3)
  return {
    setType(type){	/ / (4)
      innerType = type;
    },
    instance : status[innerType],	/ / (5)}}} ();Copy the code

Call the external function of the state method, the business is very simple, switch the current state, and then directly call the method, the code structure is very simple

function out(type = 0){
  doThings.setType(type);
  doThings.instance.first();
  // Do some other business
  doThings.instance.second();
  // ...
}
Copy the code

I think this is a highly applicable code template summarized by me. If it can be used in work, it is appropriate to directly code according to this template

advantages

In the V3 code, if we need to extend the new state, we need to do the following 2 steps

  • in(1), add a new state instance, and implement the corresponding action method
  • in(2)To establish a new mapping relationship

disadvantages

In the old code, if we need to extend the new operations doThree1(), doThree2() for the current state, we extend the switch + func() definition directly in place, which is very straightforward

With the modified template mode, we need to add a corresponding implementation of three() on each state instance at the (1) position of V3, which should be a little more troublesome compared with the old encoding mode, right?

conclusion

Good coding should be easy to read and expand. The advantages of this design are reflected in the subsequent iterations and upgrades. Although the boss only sees whether the program can run or not, if it is his turn to maintain the situation, he will leave a little time for the future