装饰器模式

为对象添加新功能

不改变其原有的结构和功能

传统 UML 类图

javascript 中的装饰器

装饰类


@testDec
clss Demo { } function testDec(target) {
target.isDec = true
} alert(Demo.isDec)

@testDec(false)
clss Demo { } function testDec(isDec) {
return function (target) {
target.isDec = isDec
}
} alert(Demo.isDec)

装饰器原理

@decorator
class A {} //等同于 class A {}
A = decorator(a) || A;

装饰类-mixin 示例

function mixins(...list) {
return function(target) {
Object.assign(target.prototype, ...list);
};
} const Foo = {
foo() {
alert("foo");
}
}; @mixins(Foo)
class MyClass {} let obj = new MyClass();
obj.foo(); // 'foo'

装饰方法

one

function readonly(target, name, descriptor) {
// descriptor对象原来的值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
} class Person {
constructor() {
this.first = "A";
this.last = "B";
} @readonly
name() {
return `${this.first} ${this.last}`;
}
} var p = new Person();
console.log(p.name()); // 调用方法
p.name = function() {}; // 这里会报错,因为 name 是只读属性

two

function log(target, name, descriptor) {
var oldValue = descriptor.value; descriptor.value = function() {
console.log(`Calling ${name} with`, arguments);
return oldValue.apply(this, arguments);
}; return descriptor;
} class Math {
@log
add(a, b) {
return a + b;
}
} const math = new Math();
const result = math.add(2, 4);
console.log("result", result);

core-decorators

  • 第三方开源 lib
  • 提供常用的装饰器
  • 文档
  • 执行npm i core-decorators --save

使用

想用什么装饰器,直接引入就行了

one

import { readonly } from "core-decorators";

class Person {
@readonly
name() {
return "zhang";
}
} let p = new Person();
alert(p.name());
// p.name = function () { /*...*/ } // 此处会报错

two

import { deprecate } from "core-decorators";

class Person {
@deprecate
facepalm() {} @deprecate("We stopped facepalming")
facepalmHard() {} @deprecate("We stopped facepalming", {
url: "http://knowyourmeme.com/memes/facepalm"
})
facepalmHarder() {}
} let person = new Person(); person.facepalm();
// DEPRECATION Person#facepalm: This function will be removed in future versions. person.facepalmHard();
// DEPRECATION Person#facepalmHard: We stopped facepalming person.facepalmHarder();
// DEPRECATION Person#facepalmHarder: We stopped facepalming
//
// See http://knowyourmeme.com/memes/facepalm for more details.

设计原则验证

  • 将现有对象和装饰器进行分离,两者独立存在
  • 符合开放封闭原则

JavaScript-装饰器模式的更多相关文章

  1. javascript装饰器模式

    装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...

  2. 从ES6重新认识JavaScript设计模式: 装饰器模式

    1 什么是装饰器模式 向一个现有的对象添加新的功能,同时又不改变其结构的设计模式被称为装饰器模式(Decorator Pattern),它是作为现有的类的一个包装(Wrapper). 可以将装饰器理解 ...

  3. JavaScript设计模式—装饰器模式

    装饰器模式介绍 为对象添加新的功能,不改变其原有的结构和功能,原有的功能还是可以使用,跟适配器模式不一样,适配器模式原有的已经不能使用了,装饰器示例比如手机壳 UML类图和代码示例 Circle示原来 ...

  4. Javascript 装饰器极速指南

    pablo.png Decorators 是ES7中添加的JavaScript新特性.熟悉Typescript的同学应该更早的接触到这个特性,TypeScript早些时候已经支持Decorators的 ...

  5. JS 设计模式九 -- 装饰器模式

    概念 装饰者(decorator)模式能够在不改变对象自身的基础上,动态的给某个对象添加额外的职责,不会影响原有接口的功能. 模拟传统面向对象语言的装饰者模式 //原始的飞机类 var Plane = ...

  6. 装饰器模式&&ES7 Decorator 装饰器

    装饰器模式(Decorator Pattern)允许向一个现有的对象动态添加新的功能,同时又不改变其结构.相比JavaScript中通过鸡肋的继承来给对象增加功能来说,装饰器模式相比生成子类更为灵活. ...

  7. PHP 装饰器模式

    装饰器模式:是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能. [装饰器模式中主要角色] 抽象组件角色(Component):定义一个对象接口,以规范准备接受附加责任的对象,即可以给这 ...

  8. 设计模式-装饰器模式(Decrator Model)

    文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...

  9. php设计模式 装饰器模式

    装饰器模式,可以动态地添加修改类的功能. 一个类提供了一项功能,如果要修改并添加额外的功能,传统的编程模式需要写一个子类继承它,并重新实现类的方法.使用装饰器模式,仅需要在运行时添加一个装饰器对象即可 ...

  10. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

随机推荐

  1. 异步查询转同步加redis业务实现的BUG分享

    在最近的性能测试中,某一个查询接口指标不通过,开发做了N次优化,最终的优化方案如下:异步查询然后转同步,再加上redis缓存.此为背景. 在测试过程中发现一个BUG:同样的请求在第一次查询结果是OK的 ...

  2. 玩转Django2.0---Django笔记建站基础九(二)(Auth认证系统)

    9.4 设置用户权限 用户权限主要是对不同的用户设置不同的功能使用权限,而每个功能主要以模型来划分.以9.3节的MyDjango项目为例,在Admin后台管理系统可以查看并设置用户权限,如下图: 用户 ...

  3. error while loading shared libraries: libevent-2.1.so.6 的解决办法

    执行 memcached 启动命令时,报错,提示:error while loading shared libraries: libevent-2.1.so.6: cannot open shared ...

  4. ASP.Net Core 发布到IIS Http Error 502.5 官方解决办法

    Http Error 502.5 - Process Failure 在IIS上发布.NET Core程序出现这个错误.网上搜索到的办法为什么总行不通呢? 有可能年代久远,现在的环境与当年不同,所以解 ...

  5. Redis(八):zset/zadd/zrange/zrembyscore 命令源码解析

    前面几篇文章,我们完全领略了redis的string,hash,list,set数据类型的实现方法,相信对redis已经不再神秘. 本篇我们将介绍redis的最后一种数据类型: zset 的相关实现. ...

  6. selenium + PhantomJS使用时 PhantomJS报错解决

    selenium + PhantomJS使用时 PhantomJS报错解决 在做动态网页爬虫时用到了selenium + PhantomJS,安装好之后运行时报错: UserWarning: Sele ...

  7. Nutz框架-- Cnd条件使用原生sql

    案例 今天接到一个临时的业务需求,做一个简单的过滤作为临时业务需要使用一两天,于是想到在原有的Cnd条件上加上一个Not like 进行过滤,但是发现现有Cnd条件查询好像满足不了 解决方案 使用Nu ...

  8. Kafka动态配置实现原理解析

    问题导读 Apache Kafka在全球各个领域各大公司获得广泛使用,得益于它强大的功能和不断完善的生态.其中Kafka动态配置是一个比较高频好用的功能,下面我们就来一探究竟. 动态配置是如何设计的? ...

  9. C/C++中指针和引用之相关问题研究

    一.基本知识 指针和引用的声明方式: 声明指针: char* pc; 声明引用: char c = 'A'                   char& rc = c; 它们的区别: ①从现 ...

  10. python 类 --导入类

    导入类 1.1.导入单个类 如何导入单个类 以上一节为例,编写一个car.py程序 编写一个新程序my_car.py 希望在my.car.py文件中直接使用car.py中的函数,使用from car ...