zoukankan      html  css  js  c++  java
  • 设计模式--装饰器模式

    概念:

    装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。

    其实,就是创建一个包装器,里面有增强的功能,然后把目标对象给套住,就直接使用包装器对象。

    UML:

     es6:

    class Circle {
        draw() {
            console.log("画一个圆形");
        }
    }
    
    class Decorator {
        constructor(circle){
            this.circle = circle;
        }
        draw() {
            this.circle.draw();
            this.setRedBorder(this.circle);
        }
        setRedBorder(circle) {
            console.log("设置红色边框")
        }
    }
    // 测试代码
    let circle = new Circle();
    let decorator= new Decorator(circle);
    decorator.draw();

     es7:

    function borderDecorator(target, key, descriptor) {
        const method = descriptor.value;
        
        descriptor.value = () => {
            method.apply(target);
            console.log("设置红色边框")
        }
        
        return descriptor;
    }
    
    class Circle {
        @borderDecorator
        draw() {
            console.log("画一个圆形");
        }
    }
    
    
    // 测试代码
    let circle = new Circle();
    circle.draw();

     对某个函数增强功能:

    const memoize = function(f) {
            const cache = {};
            return function() {
                const argStr = JSON.stringify(arguments);
                
                if (!cache[argStr]) {
                    cache[argStr] = f.apply(f, arguments);
                }
                
                return cache[argStr];
            }
        }

    函数f没有缓存功能, 在没有修改原函数的情况下,通过闭包,套了一层,就具有缓存的功能了。

    优点:

    • 装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
    • 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。
    • 通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
    • 具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”

    缺点:

    • 使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。
    • 这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
  • 相关阅读:
    PHP命名空间
    php各个版本的区别
    MySQL的读写分离---主从复制、主主复制
    redis的安装和php的redis扩展
    php的设计模式
    git命令详情
    memcache和redis的对比
    mysql性能优化
    MySQL的分区、分表、集群
    nginx的反向代理和负载均衡
  • 原文地址:https://www.cnblogs.com/bigman-bugman/p/12273673.html
Copyright © 2011-2022 走看看