JS设计模式-构造器模式,工厂模式,单例模式

981 阅读3分钟

设计模式核心思想:封装变化。 

找到程序中的变和不变,然后将变和不变的代码分离开来, 达到变化的部分更加灵活,不变的那就更加稳定。

1,能用健壮的代码去解决具体的问题。

2,能用抽象的思维去应对复杂的系统。

3,能用工程化思维去规划更大规模的业务。 

一,构造器模式

// 构造器模式        
            function User(name, age, career) {            
                        this.name = name;            
                        this.age = age;            
                        this.career = caches;        
                   }        
            const user = new User(name, age, career)

未使用工厂模式时可能随着业务的增加,会写出屎山一样的代码如下

                function Boss(name, age) {            
                            this.name = name;        
                            this.age = age;            
                            this.career = "老板";            
                            this.work = ["喝茶", "看报"]        
                        }        
                function Worker(name, age) {            
                             this.name = name;            
                             this.age = age;            
                             this.career = "员工";           
                             this.work = ["干活", "开会"]        
                         }        
                function Factory(name, age, career) {            
                             switch(career){                
                                    case "老板":                    
                                 return new Boss(name,age)                    
                                 break                
                                    case "员工":                    
                                 return new Worker(name, age)                    
                                 break                    
                                    // ...            
                                }        
                          }

 二,工厂模式 

2.1 简单工厂模式

// 简单工厂模式        
              function User1(name, age, career, work) {            
                           this.name = name;            
                           this.age = age;            
                           this.career = career;            
                           this.work = work;        
                       }        
             function Factory(name, age, career) {            
                        let work;            
                        switch(career) {                
                             case "老板":                    
                                  work = ["喝茶", "看报"];                    
                             break;                
                             case "员工":                   
                                  work = ["干活", "开会"];                    
                             break;                
                            // ...            
                        }            
                   return new User1(name, age, career, work);        
                 }

2.2 抽象工厂模式

抽象工厂不可否认它在强类型语言中非常有用, 比如在Java和C++中就经常使用。因为这些语言在创建对象时,需要时刻关注类型之间的解耦, 以便该对象日后可以表现多态性。但JavaScript是弱类型语言,就是说自带多态, 所以开发中我们不考虑这部分的解耦。

 开放封闭原则基本思想是一个类只应该对外暴露它所需要的接口,而不应该暴露其内部的实现细节。

// 抽象工厂模式        
                class ETFactory{            
                     // 场地门市接口            
                     createStore() {                
                     throw new Error("抽象方法,不允许直接调用,需要重写")            
                      }            
                     // 服务人员接口            
                     createUser() {               
                     throw new Error("抽象方法,不允许直接调用,需要重写")            
                      }        
                  }        
// 具体工厂类(实现类)继承抽象工厂                
                 class Store{            
                      getAddress() {                
                      throw new Error("抽象方法,不允许直接调用,需要重写")            
                     }        
                  }        
                class WanDaStore extends Store{            
                     getAddress() {                
                     console.log('万达广场一楼')            
                    }        
                 }        
               class WanXiangStore extends Store{            
                    getAddress() {                
                       console.log('万象城一楼')            
                     }        
                 }        
               class Technician{            
                    getSkill() {                
                         throw new Error("抽象方法,需要重写")            
                       }        
                   }        
              class SPATechnician extends Technician{            
                      getSkill() {                
                          console.log('销售')            
                      }        
                  }        
              class SoftTechnician extends Technician{            
                      getSkill() {                
                          console.log('演讲')            
                      }        
                  }        
               class AchieveFactory extends ETFactory{            
                      createStore() {               
                            return new WanDaStore();            
                       }            
                      createUser() {                
                            return new SPATechnician();            
                       }        
                }        
              const myHongLangMan = new AchieveFactory();        
              const myStore = myHongLangMan.createStore();        
              const technician = myHongLangMan.createUser();        
              myStore.getAddress()        
              technician.getSkill()

三,单例模式

普通方法

// 普通方法        
            class CommonDemo {            
                   show() {                
                       console.log("我是一个普通方法");            
                      }        
                 }        
            const common1 = new CommonDemo();        
            const common2 = new CommonDemo();        
            console.log(common1 === common2); // false

 实现单例模式的方法:使用构造函数,静态方法,闭包。

3.1 用构造函数实现

 // 用构造函数实现单例模式        
               let singleDemo;       
               function SingleDemo() {            
                       if(!singleDemo) {                
                            singleDemo = this;            
                        }            
                   return singleDemo;       
                }        
              SingleDemo.prototype.show = function() {        
                        console.log("我是一个单例模式");       
                }        
             const single1 = new SingleDemo();    
             const single2 = new SingleDemo();      
             console.log(single1 === single2) // true

3.2 用静态方法实现

 // 使用静态方法实现单例模式        
              class SingleDemo1 {            
                      show() {            
                         console.log("我是一个单例模式");    
                       }         
              static getInstance() {        
                       if(!SingleDemo1.instance) {           
                             SingleDemo1.instance = new SingleDemo1();        
                         }               
                     return SingleDemo1.instance;         
                   }     
                }        
              const single3 = SingleDemo1.getInstance();       
              const single4 = SingleDemo1.getInstance();       
              console.log(single3 === single4) // true

3.3 用闭包实现

静态方法存在于类中,但是不属于任何实例。直接属于类本身。 在调用静态方法时,不需要创建类的实例。直接通过类名调用。

闭包的三个基本特点:

1,闭包可以访问外部函数的变量,即时外部函数已经返回了 。

2,闭包保存外部函数变量的引用,而不是实际的值。

3,每当一个函数在另一个函数中被创建时,就会产生闭包。

// 使用闭包实现单例模式        
           class SingleDemo2 {           
                     show() {              
                          console.log("我是一个单例模式");      
                       }      
                    }        
            SingleDemo2.getInstance = (function(){           
                          let instance = null;          
                          return function() {           
                                  if(!instance){       
                                      instance = new SingleDemo2();      
                            }           
                        return instance;     
                      }     
             })();        
          const single5 = SingleDemo2.getInstance();    
          const single6 = SingleDemo2.getInstance();   
          console.log(single3 === single4) // true