作用

JavaScript设计模式的作用 - 提高代码的重用性,可读性,使代码更容易的维护和扩展。

目录

  1. 单例模式
  2. 工厂模式
  3. 抽象工厂模式
  4. 策略模式
  5. 模板方法模式
  6. 职责链模式
  7. 发布订阅者模式
  8. 桥接模式
  9. 适配器模式
  10. 代理模式

    正文

  • 单例模式

    确保一个类仅有一个实例,并提供一个访问它的全局访问点。一般我们是这样实现单例的,用一个变量来标志当前的类已经创建过对象,如果下次获取当前类的实例时,直接返回之前创建的对象即可

单例模式下对象只会实例化一次,我们可以利用闭包,当该对象已经存在的时候,直接返回该对象,否则重新创建

1
2
3
4
5
6
7
8
9
var singleton = function( fn ){
var result;
return function(){
return result || ( result = fn .apply( this, arguments ) );
}
}
var createMask = singleton( function(){
return document.body.appendChild( document.createElement('div') );
})

http://www.alloyteam.com/2012/10/common-javascript-design-patterns/

  • 工厂模式

    提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。
    工厂就是把成员对象的创建工作转交给一个外部对象,好处在于消除对象之间的耦合(何为耦合?就是相互影响)。通过使用工厂方法而不是new关键字及具体类,可以把所有实例化的代码都集中在一个位置,有助于创建模块化的代码,这才是工厂模式的目的和优势。

能解决多个相似的问题,但不能知道对象识别的问题(对象的类型不知道)
使用工厂模式生成xhr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var XMLHttpFactory =function(){};      //这是一个简单工厂模式
  XMLHttpFactory.createXMLHttp =function(){
     var XMLHttp = null;
    if (window.XMLHttpRequest){
      XMLHttp = new XMLHttpRequest()
     }elseif (window.ActiveXObject){
      XMLHttp = new ActiveXObject("Microsoft.XMLHTTP")
    }
  return XMLHttp;
  }
  //XMLHttpFactory.createXMLHttp()这个方法根据当前环境的具体情况返回一个XHR对象。
  var AjaxHander =function(){
    var XMLHttp = XMLHttpFactory.createXMLHttp();
         ...
  }
  • 抽象工厂模式

    将其成员对象的实列化推迟到子类中,子类可以重写父类接口方法以便创建的时候指定自己的对象类型。 父类就变成了一个抽象类,但是父类可以执行子类中相同类似的方法,具体的业务逻辑需要放在子类中去实现。

定义函数实现子类继承父类,然后子类重写父类中的抽象方法。
工厂中定义多个抽象类,实现具体子类继承抽象类
实现方式—>https://segmentfault.com/a/1190000012422055

  • 策略模式

    定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换
    使用策略模式重构代码,可以消除程序中大片的条件分支语句。在实际开发中,我们通常会把算法的含义扩散开来,使策略模式也可以用来封装一系列的“业务规则”。只要这些业务规则指向的目标一致,并且可以被替换使用,我们就可以使用策略模式来封装他们

普通模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var awardS = function (salary) {
return salary * 4
};

var awardA = function (salary) {
return salary * 3
};

var awardB = function (salary) {
return salary * 2
};

var calculateBonus = function (level, salary) {
if (level === 'S') {
return awardS(salary);
}
if (level === 'A') {
return awardA(salary);
}
if (level === 'B') {
return awardB(salary);
}
};

calculateBonus('A', 10000);

策略模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var strategies = {
'S': function (salary) {
return salary * 4;
},
'A': function (salary) {
return salary * 3;
},
'B': function (salary) {
return salary * 2;
}
}

var calculateBonus = function (level, salary) {
return strategies[level](salary);
}

calculateBonus('A', 10000);
  • 模板方法模式

    模板方法模式使用了原型链的方法,封装性好,复用性差
    模板方法模式由二部分组成,第一部分是抽象父类,第二部分是具体实现的子类,一般的情况下是抽象父类封装了子类的算法框架,包括实现一些公共方法及封装子类中所有方法的执行顺序,子类可以继承这个父类,并且可以在子类中重写父类的方法,从而实现自己的业务逻辑。

模板方法是基于继承的设计模式,可以很好的提高系统的扩展性。 java中的抽象父类、子类
模板方法有两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。

实现:父类定义方法,子类实现方法(抽象工厂模式封装了继承函数)。
示例—->https://blog.csdn.net/ligang2585116/article/details/50365276

  • 职责链模式

    职责链,一系列可能处理请求的对象被连接成一条链,请求在这些对象之间依次传递,直到遇到一个可以处理它的对象,减少了很多重复代码。

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

https://div.io/topic/1800#1%E8%81%8C%E8%B4%A3%E9%93%BE%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%AE%9A%E4%B9%89

  • 发布订阅者模式(观察者模式)

    发布订阅模式,顾名思义,就是一个发布消息,一个监听消息,当有消息接收时处理消息。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    function Publisher(name) {
    this.name = '报纸' + name
    // 订阅了本出版社的读者列表
    this.subscribers = [];
    }

    // 添加一个迭代方法,遍历所有投递列表
    Publisher.prototype.deliver = function(data) {
    // 遍历当前出版社对象所有的订阅过的方法
    const context = this
    this.subscribers.forEach(function(fn) {
    //data用于传参数给内部方法
    fn.fire(context.name, data);
    });
    return this;
    }


    // 观察者
    function Observe(callback) {
    this.fire = callback;
    }

    // 给予订阅者阅读的能力
    Observe.prototype.subscribe = function(publisher) {

    var that = this;
    // some如果有一个返回值为true则为true
    var alreadyExists = publisher.subscribers.some(function(el){
    // 这里的el指的是函数对象
    return el.fire === that.fire // 查看是否已经订阅了,如果订阅了就不再订阅
    });

    // 如果存在这个函数对象则不进行添加
    if (!alreadyExists) {
    publisher.subscribers.push(this);
    }
    return this;
    };

    // 给予观察者退订的能力
    Observe.prototype.unsubscribe = function(publisher) {

    var that = this;

    // 过滤,将返回值为true的重组成数组
    publisher.subscribers = publisher.subscribers.filter(function(el) {

    // 这里的el.fire指的是观察者传入的callback
    // that.fire就是当前对象对callback的引用
    return !(el.fire === that.fire) // 删除掉订阅
    })
    return this;
    };

    var publisher1 = new Publisher('xixi');

    // 实例化的读者,这个需要改进
    var observer1 = new Observe(function(publisher, text) {
    console.log('得到来自'+publisher +'的订阅消息:'+ text + ',哈哈哈')
    });
    var observer2 = new Observe(function(publisher, text) {
    console.log('得到来自'+publisher +'的订阅消息:'+ text + ',嘻嘻嘻')
    });

    // 读者订阅了一家报纸,在报社可以查询到该读者已经在订阅者列表了,
    // publisher1.subscribers->[observer1]
    observer1.subscribe(publisher1);
    observer2.subscribe(publisher1)
    // 分发报纸,执行所有内在方法
    publisher1.deliver(13);// 输出123

    // 退订
    observer1.unsubscribe(publisher1);
    publisher1.deliver(12388);
  • 桥接模式
    https://segmentfault.com/a/1190000012547750
  • 适配器模式

    适配器模式(Adapter)是将一个类(对象)的接口(方法或属性)转化成客户希望的另外一个接口(方法或属性),适配器模式使得原本由于接口不兼容而不能一起工作的那些类(对象)可以一些工作。

https://segmentfault.com/a/1190000012436538

  • 代理模式

    代理模式的定义是把对一个对象的访问, 交给另一个代理对象来操作.

保护代理、虚拟代理(图片预加载)、缓存代理
https://juejin.im/post/5a68491cf265da3e5661b342#heading-0

感谢您的阅读,本文由 Astar 版权所有。如若转载,请注明出处:Astar(http://example.com/2021/12/12/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/
实现平衡二叉树AVL
排序算法