首页 js设计模式-装饰者模式
文章
取消

js设计模式-装饰者模式

装饰者模式

装饰者模式,在js设计模式书中以自行车售卖为例做了讲解:一辆自行车是一个基础类,现在要根据不同的用户需求,
可能需求加车前灯、后灯、车铃、刹车盘、轮毅等,对应的价格也会再基础类之上有所不同。前灯、后灯、刹车盘。。。
就是自行车的装饰。装饰者模式的大概理解如此。

抽离封装、继承、多态、是贯穿于世间所有科学发展的项目的哈,包括软件、硬件,以及实体建筑工程、工业、等等。。。,然后作用到实际场景、维度、可能名称会有点大同小异,但是哲学理念是一样的。装饰器模式和适配器模式从实现哲理上还是有类似的共通之处的,只是作用维度不同,名称不同,细节不同。—当我们要学习使用它的时候,还是要落到实处去学习一下具体应用领域的专业细节的。

由于装饰者模式在js的具体示例适当有点冗长,该篇文章也是本人对该模式的阅读之后的理解,希望帮自己增进知识,也顺便可能帮到别人

我个人认为这个模式,应该先从概念理解和优缺点以及应用场景开始讲比较好。

装饰者模式优点

装饰者是在运行期间为对象增添特性或职责的有力工具。在自行车商店那个例子中,逦过使 用裝饰者,你可以动态地为自行车对象添加可选的特色配件。在只有部分对象需要这些特性的情 况下装饰者模式的好处尤为突出。如果不采用这种模式,那么要想实现同样的效果必须使用大量 子类。

裝饰者的运作过程是透明的,这就是说你可以用它包装其他对象,然后继续按之前使用那些 对象的方法来使用它。从MethodProfiler这个示例中可以看到,这一切甚至可以动态实现,不用 事先知道组件对象的接口。在为现有对象添砖加瓦这方面,装饰者模式为程序员带来了极大的灵 活性。

甜美

装饰者模式缺点

装饰者模式的缺点主要表现在两个方面:
首先,在遇到用装饰者包装起来的对象时,那些依赖于类型检查的代码会出问题。
尽管在JavaScript中很少使用严格的类型检查,但是如果你的代码中执行了这样的检查,
那么装饰者是无法匹配所需要的类型的。通常装饰者对客户代码来说是完全透明的,
不过,在这种情况下,客户代码就能感知装饰者与其组件的不同。

其次,使用装饰者模式往往会增加架构的复杂程度。这种模式常常要引入许多小对象,它们 看起来比较相似(参见自行车商店一例),而实际功能却大相径庭。装饰者棪式往往不太容易理 解,对于那些不熟悉这种模式的开发人员而言尤其如此。此外,实现具有动态接口的装饰者(如 MethodProfiler)沙及的语法细节有时也会令人生畏。在设计一个使用了装饰者模式的架构时, 你必须多花点心思,确保自己的代码有良好的文档说明,并且容易理解。

总之

本章讲述了一种既不用创建子类,又能透明、动态地为对象增添功能的设计模式。装饰者棪 式可以在不修改类定义的前提下用来为具体对象添加特性。我们再次研究了自行车商店的例子, 并用工厂模式来创建具有多种可定制选件的自行车。我们讨论了装饰者修改其包装的对象的各种 做法,以及与每种做法相关的一些注意事项。作为一个实用性的练习,我们还创建了一个具有动 态接口的装饰者,它可以用来记录执行一个对象的方法所耗费的时间。

只要懂得裝饰者模式的工作机制,你就会明白它是多么有用。我们用7个装饰者就完成了本 *需要几千个子类才能完成的任务,这足以说明问题。监于装饰者的完全透明性,使用这种模式 时你不用老是担心系统会因此而失灵或产生不兼容问题。这是一种不用重新定义对象就能对其进 行扩充的简便手段。

尽可能建议在合适需要的地方,该用的地方再用,这个要自己判断一下

用一天的时间,抽空看完一种设计模式,或者两天,还是有收获的,我们需要耐心,这个从长远来说,不算慢的。

下面讲一下具体案例

装饰器是装饰者模式的具体实现,现实应用中,typescript对装饰器模式有明确的使用实现。 比如类的装饰可以类似下面这样: // 类的装饰器

1
2
3
4
5
6
7
8
9
10
  @decortaor
  class MyTestableClass {
    // ...
  }

  function decortaor(target){
    target.isTestable = true;
  }

  MyTestableClass.isTestable  // true;

// 装饰类的属性

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
 class Person{
  @readonly
  name(){
    return this.first;
  }
 }

 function readonly(target,name,descriptor){
   // descriptor对象原来的值如下
  // {
  //   value: specifiedFunction,
  //   enumerable: false,
  //   configurable: true,
  //   writable: true
  // };
  descriptor.writeable = false;
  return descriptor;
 }

 readonly(Person.prototype,'name',descriptor)
//  类似于
Object.defineProperty(Person.prototype,'naem',descriptor)


// 类的方法装饰器
class C{
  @addPrefix
  toString(){
    return 'str'
  }
}

function addPrefix(target){
  return 'pre'+target()
}
// 相当于 C.prototype.toString = addPrefix(C.prototype.toString)

上面的部分示例装饰typescript的应用实现,如果用原生js实现装饰者模式 可以大概如下这样:

比如我们文章顶部提到的,装饰者模式原文中举例的 自行车商店案例,可以大概的原生js实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  //自行车商店有两种类型的自行车,例如山地车、公路车。 然后自行车又有刹车、按铃、售后维修、等服务,对应的价格也会不同。我们要获取对应的报价
  function Bicycle(){}
  Bicycle.prototype.getPrice = function(){
    return 1000;
  }

  function BicycleRailway(){}
  BicycleRailway.prototype.price = 1500;

  function BicycleMountain(){}
  BicycleMountain.prototype.price = 1000;


  // const BicycleShop = {
  //   BicycleRailway,
  //   BicycleMountain
  // }

  const DecoratorBell = function(){}

  extends(DecoratorBell,Bicycle);
  DecoratorBell.prototype.price = 

对于框架的理解,框架和类库的区别

js设计模式-组合模式