设计模式(一)

零、原则

S – Single Responsibility Principle 单一职责原则

  • 一个程序只做好一件事
  • 如果功能过于复杂就拆分开,每个部分保持独立

O – OpenClosed Principle 开放/封闭原则

  • 对扩展开放,对修改封闭
  • 增加需求时,扩展新代码,而非修改已有代码

L – Liskov Substitution Principle 里氏替换原则

  • 子类能覆盖父类
  • 父类能出现的地方子类就能出现

I – Interface Segregation Principle 接口隔离原则

  • 保持接口的单一独立
  • 类似单一职责原则,这里更关注接口

D – Dependency Inversion Principle 依赖倒转原则

  • 面向接口编程,依赖于抽象而不依赖于具体
  • 使用方只关注接口而不关注具体类的实现

一、工厂模式

创建对象,使一个类的实例化延迟到了子类内。

  • 模式作用:

    1. 对象的构建十分复杂。
    2. 需要依赖具体的环境创建不同实例。
    3. 处理大量具有相同属性的小对象。
  • 注意事项:

    1. 不能滥用工厂,有时候仅仅是给代码增加复杂度。
  • 示例:

    // 简单工厂
    class Apple {
      phone(){
        console.log('iPhone');
      }
    }
    class SAMSUNG {
      phone(){
        console.log('Galaxy');
      }
    }
    class Factory {
      create(type){
          // 复杂操作
        let obj = null;
        switch (type) {
          case 'Apple':
            obj = new Apple();
            break;
          case 'SAMSUNG':
            obj = new SAMSUNG();
            break;
          default:
            new Error('No type!');
        }
        return obj;
      }
    }
    let factory = new Factory()
    let phone1 = factory.create('Apple');
    let phone2 = factory.create('SAMSUNG');
    phone1.phone(); // iPhone
    phone2.phone(); // Galaxy
    // 或者直接添加在工厂类上添加方法
    class Apple {
      phone(){
        console.log('iPhone');
      }
    }
    class SAMSUNG {
      phone(){
        console.log('Galaxy');
      }
    }
    class Factory {
    }
    Factory.create = function(type){
      let obj = null;
        switch (type) {
          case 'Apple':
            obj = new Apple();
            break;
          case 'SAMSUNG':
            obj = new SAMSUNG();
            break;
          default:
            new Error('No type!');
        }
        return obj;
    }
    let phone1 = Factory.create('Apple');
    let phone2 = Factory.create('SAMSUNG');
    phone1.phone(); // iPhone
    phone2.phone(); // Galaxy

拓展:抽象的来说,工厂可以根据类型来生产产品,或是在子类中覆盖或添加其他的东西。

二、单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 模式作用:

    一个单一对象,比如弹窗,无论点击多少次,弹窗只应该被创建一次。

  • 示例:

    class CreateUser {
        constructor(name) {
            this.name = name;
            this.getName();
        }
        getName() {
             return this.name;
        }
    }
    // 代理实现单例模式
    var ProxyMode = (function() {
        var instance = null;
        return function(name) {
            if(!instance) {
                instance = new CreateUser(name);
            }
            return instance;
        }
    })();
    // 测试单体模式的实例
    var a = new ProxyMode("aaa");
    var b = new ProxyMode("bbb");
    // 因为单体模式是只实例化一次,所以下面的实例是相等的
    console.log(a === b);    //true
    // ************************************************
    class LoginForm {
      constructor() {
        this.state = 'hide'
      }
      show() {
        if (this.state === 'show') {
          alert('已经显示')
          return
        }
        this.state = 'show'
        console.log('登录框显示成功')
      }
      hide() {
        if (this.state === 'hide') {
          alert('已经隐藏')
          return
        }
        this.state = 'hide'
        console.log('登录框隐藏成功')
      }
    }
    LoginForm.getInstance = (function () {
      let instance
      return function () {
        if (!instance) {
          instance = new LoginForm()
        }
        return instance
      }
    })()
    let obj1 = LoginForm.getInstance()
    obj1.show()
    let obj2 = LoginForm.getInstance()
    obj2.hide()
    console.log(obj1 === obj2)

三、策略模式

第一个部分是一组策略类(可变),策略类封装了具体的算法,并负责具体的计算过程。第二个部分是环境类(不变),接受客户的请求,随后将请求委托给某一个策略类。

  • 作用:

    1. 将实现和使用分开。
    2. 避免多重条件选择语句。
    3. 符合开放-封闭原则,将算法封装在独立的策略中,使得它们易于切换、扩展。
  • 示例:

    /*策略类*/
    var levelOBJ = {
        "A": function(money) {
            return money * 4;
        },
        "B" : function(money) {
            return money * 3;
        },
        "C" : function(money) {
            return money * 2;
        } 
    };
    /*环境类*/
    var calculateBouns =function(level,money) {
        return levelOBJ[level](money);
    };
    console.log(calculateBouns('A',10000)); // 40000

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!

页面布局 Previous
预处理器 Next