Simple Factory model

The factory pattern encapsulates the process of creating objects. Just like the factory, we don’t need to care how the factory makes things, we just need to provide the materials, we can get what we want.

Start with a simple constructor.

function clothes(color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender 
}
Copy the code
const clotheA = new Clothes(color, size, gender)
Copy the code

Good, we can make a lot of Clothes by Clothes, but now there are only three kinds of Clothes: color, size, and gender. There is no distinction between jacket and pants. If need be added:

function Jacket(color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender 
    this.kind = 'coat'
}
function Sweater (color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender 
    this.kind = 'sweaters'
}
function Jeans (color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender 
    this.kind = 'Jeans'
}
Copy the code

Obviously, if there are many kinds of clothes, you need to create many constructors. So, we can build a factory to help us solve this tedious operation.

function clothes(color, size, gender,kind) {
    this.color = color
    this.size = size
    this.gender = gender 
    this.kind = kind 
}
function clotheFactory(color, size, gender,kind) {
    switch(kind) {
        case 'Jacket':
            kind = 'coat'
            break
        case 'Sweater':
            kind = 'sweaters'
            break
        case 'Jeans':
            kind = 'Jeans'
            break
        }
        return new Clothes(color, size, gender, kind)
}
let Jacket = clotheFactory('red'.'43 yards'.'men'.'Jacket'); 
console.log(Jacket) / / thanks {color: "red", size: 43 yards, gender: "men", kind: "coat"}
Copy the code

The singleton pattern

What is the singleton pattern? The singleton pattern ensures that a class has only one instance and provides a global access point to access it.

function clothes(color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender 
}
const ClothesA = new Clothes('red'.'43 yards'.'men')
const ClothesB = new Clothes('red'.'43 yards'.'men')
console.log(ClothesA ===ClothesB);//false
Copy the code

Obviously ClothesA and ClothesB are separate objects, each occupying a chunk of memory, which is not what we want.

A simple way to implement a singleton pattern is to use a variable to indicate whether an instance of a class has already been created, and if so, the next time an instance of that class is fetched, the previously created instance is returned.

function clothes(color, size, gender) {
    this.color = color
    this.size = size
    this.gender = gender
    this.instance = null // To indicate whether an instance has been created
}
Clothes.prototype.getColor = function(){ 
 console.log ( this.color ); 
};
// To check whether an instance has been created
Clothes.getInstance = function( color ){ 
 if(!this.instance ){ 
 this.instance = new Clothes( color ); 
 } 
 return this.instance; 
};
var ClothesA =  Clothes.getInstance('red')
var ClothesB =  Clothes.getInstance('yellow')
console.log(ClothesA === ClothesB);//true
Copy the code

Of course, this can also be implemented in the form of closures.

Clothes.getInstance = (function( color ){ 
    let instance = null
    return function(){
        if(! instance ){ instance =newClothes( color ); }}returninstance; }) ()Copy the code

The strategy pattern

The definition of a strategy pattern is to define a series of algorithms, encapsulate them one by one, and make them interchangeable.

But it’s a little hard to understand when you look at the definition, so I can use some simple examples.

Consider this scenario: one day, the company has had a good quarter, and the boss is going to give a performance bonus to each employee.

If the employee’s performance is excellent, the salary will be +20% of the original basic salary. Employee performance is good, salary on the original basic salary +10% performance. The employee’s performance is passing, and the salary will be 5% above the original basic salary.

If you were a junior developer looking at this scenario, you might write something like this:

function getSalary(grade,basicSalary){
    if(grade==='best') {return basicSalary * 1.2
    }
    if(grade==='good') {return basicSalary * 1.1
    } 
    if(grade==='pass') {return basicSalary * 1.05}}Copy the code

Functionally this is fine, but handling multiple logics in a single function clearly violates the “single function” principle.

So we can make some adjustments.

function gradeYou(basicSalary){
    return basicSalary * 1.2
}
function gradeliang(basicSalary){
    return basicSalary * 1.1
}
function gradeJige(basicSalary){
    return basicSalary * 1.05
}
function getSalary(grade,basicSalary){
    if(grade==='excellent') {return gradeYou(basicSalary)
    }
    if(grade==='good') {return gradeliang(basicSalary)
    } 
    if(grade==='pass') {return gradeJige(basicSalary)
    }
}
Copy the code

Ok, now each function only does one thing, but there’s still a lot of if in getSalary(), and if the boss says there’s no performance bonus for the flunked person, then you have to add another if.

function getSalary(grade,basicSalary){
    if(grade==='excellent') {return gradeYou(basicSalary)
    }
    if(grade==='good') {return gradeliang(basicSalary)
    } 
    if(grade==='pass') {return gradeJige(basicSalary)
    }
     if(grade==='fail') {return gradeBujige(basicSalary)
    }
}
Copy the code

This clearly does not conform to the “open and closed” principle of separating the invariable part from the changing part. In order to achieve open to extension, closed to modification. We can use the form of object mapping.

var salaryRule = {
    excellent(basicSalary) {
        return basicSalary * 1.2
    },
    good(basicSalary) {
        return basicSalary * 1.1
    }, 
    pass(basicSalary) {
        return basicSalary * 1.05}},function getSalary(grade, basicSalary) {
  return salaryRule[grade](basicSalary)
}
Copy the code

If you want to add a fail later, just add a new mapping to salaryRule

salaryRule.fail = function (basicSalary){
return basicSalary
}
Copy the code

reference

JavaScript Design Patterns and Development Practices

Core Principles and Application practice of JavaScript Design Patterns