JavaScript设计模式之装饰器模式

发布于 / 学习

介绍

  • 为对象添加新功能
  • 不改变其原有的结构和功能

实例

  • 手机壳(只是增加装饰、防摔功能)

UML

image
– 通过DecortorCircle新增setRedBorder()方法

代码演示

    //圆
    class Circle{
        draw(){
            console.log('画一个圆')
        }
    }
    //装饰器
    class Decorator{
        constructor(circle){
            this.circle = circle
        }
        draw(){
            this.circle.draw()
            this.setRedBorder(circle)
        }
        setRedBorder(circle){
            console.log('设置了红色边框')
        }
    }

    //测试
    let circle = new Circle()
    circle.draw()

    let dec = new Decorator(circle)

    dec.draw()
  • result
    image

场景

  • es7装饰器
  • code-decorators

es7装饰器

  • 配置环境
  • 装饰类
  • 装饰方法
配置环境
  • 安装插件
 npm install babel-plugin-transform-decorator-legacy --save-dev
  • 修改.babelrc
    {
        "plugins":["transform-decorator-legacy"]
    }
装饰类
  • 普通装饰类
    //装饰类
    @testDec
    class Demo{
            // ...
    }
    function testDec(target) {
        target.isDec = true
    }
     alert(Demo.isDec) //true
  1. @testDec为Class增加了一个装饰器`
  2. target其实就是Demo
  • 带参数
        @testDec
        @testDecParams(false)
        class Demo{
            // ...
        }
        //装饰类 不带参数
        function testDec(target) {
            target.isDec = true
        }

        alert(Demo.isDec) //true

        //装饰类 带参数
        function testDecParams(isDec) {
            return function (target) {
                target.isDec = isDec
            }
        }
  • mixins实例
    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()
装饰方法
     class Person{
        constructor(){
            this.first = 'A'
            this.last = 'B'
        }

        //装饰方法
        @readOnly
        name(){
            return this.first +'-' + this.last
        }
    }
    function readOnly(target,name,descriptor) {
        //descriptor 属性描述对象
        // {
        //     value:specifiedFunction,
        //     enmerable:false,
        //     configurable:true,
        //     writable:true
        // }
        descriptor.writable = false
        return descriptor
    }

    const  p = new Person()
    console.log(p.name())
    //p.name = function(){} //报错  只读
  • 定义一个只读方法,修改属性描述对象中的是否可写

场景

  • core-decorators 提供常用的装饰器

原文:https://www.ahwgs.cn/javascriptshejim…zhuangshiqimoshi.html
代码:https://github.com/ahwgs/design-pattern-learning/tree/master/6.JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E4%B9%8B%E8%A3%85%E9%A5%B0%E5%99%A8%E6%A8%A1%E5%BC%8F

本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可
本文链接: https://www.ahwgs.cn/javascriptshejimoshizhizhuangshiqimoshi.html