javascript设计模式-装饰者

这篇具有很好参考价值的文章主要介绍了javascript设计模式-装饰者。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

装饰者

基本实现

是一种为对象增加我的技术,它并不使用创建新子类手段,一切都在动态完成。这个过程相对于使用者来说是透明的。透明地把对象包装在具有同样接口的另一个对象之中。

比如可以动态的为自行车对象添加可选的特色配件上。比如添加4个选件,可以新定义4个超类,但如果自行车种类过多,则需要派生出N多子类。基本是不可以维护。如果用装饰者,只需要维护4个类即可,一个选件一个类。通过装饰加在各个原有的自行车上。

缺点在于,在遇到用装饰者包装起来的对象时,那些依赖于类型检查的代码会出问题,所以在设计此模式的类时不要使用类型检查。另外一点这种模式常常要引入许多小对象,它们看起来差不多,实际功能却大相径庭。所以使用此模式时要仔细,因为它的代码和API都不容易设计和使用。它的架构如下:

/* The Bicycle interface. */
var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'getPrice']);

/* 自行车实例. */
var AcmeComfortCruiser = function() { };// implements Bicycle
AcmeComfortCruiser.prototype = {
  assemble: function() {
  },
  wash: function() {
  },
  getPrice: function() {
    return 399.00;
  }
};
/* 选件类,其实就是装饰者类,所有自行车和装饰者都需要实现Bicycle接口.装饰者模式颇多得益于接口的使用,其最重要的特点之一就是它可以用来替代组件,原来使用AcmeComfortCruiser的地方都可以用装饰类来代替而不用修改源代码,下面的装饰类对原类的两个方法进行了装饰。 * 下面的superclass是个自定义的属性,是在extends方法中加上的*/
var HeadlightDecorator = function(bicycle) { // implements Bicycle
    HeadlightDecorator.superclass.constructor.call(this, bicycle);
}
extend(HeadlightDecorator, BicycleDecorator); // Extend the superclass.
HeadlightDecorator.prototype.assemble = function() {
  return this.bicycle.assemble() + ' Attach headlight to handlebars.';
};
HeadlightDecorator.prototype.getPrice = function() {
  return this.bicycle.getPrice() + 15.00;
};
var myBicycle= newAcmeComfortCruiser();//裸自行车
var myBicycle = new TaillightDecorator(myBicycle); //加了一个篮子
myBicycle = new TaillightDecorator(myBicycle); //又加了另一个篮子
alert(myBicycle.getPrice());  //得到最终的价格

简单的组合模式和装饰者模式基本一样,但有些本质的区别,组合对象并不修改方法调用,其着眼于组织对象。而装饰者存在的唯一目的就是修改方法调用而不是组织子对象,因为子对象只有一个。

装饰者的作用在于以某种方式对其组件对象的行为进行修改。这种修改可以体现在方法之前、之后添加行为或是直接替换方法,甚至添加新的方法。

上例中一次只能添加一个选件,如果多个选件,需要多次调用即可。

HeadlightDecorator.prototype.getPrice = function() {
  return this.bicycle.getPrice() + 15.00;//之后};
var FrameColorDecorator = function(bicycle, frameColor) { //implements Bicycle
  this.superclass.constructor(bicycle); // Call the superclass's constructor.
  this.frameColor = frameColor;
}
extend(FrameColorDecorator, BicycleDecorator); // Extend the superclass.FrameColorDecorator.prototype.assemble = function() {
  return 'Paint the frame ' + this.frameColor + ' and allow it to dry. ' + 
      this.bicycle.assemble();//之前,注意这个参数的传递};
LifetimeWarrantyDecorator.prototype.repair = function() {
  return 'This bicycle is covered by a lifetime warranty. Please take it to ' +'an authorized Acme Repair Center.';
};//直接替换掉原来的方法实现

添加新方法时需要注意,因为接口中并没有声明,又不适合直接改接口,这样很多装饰子类中可能会有很多无用的代码,最好的方法是使用一种称为pass-through method的技术,暂时没搞清楚其运行机制。

OUTERLOOP:对组件对象进行检查 ,并为其拥有的每一个方法创建一个通道方法。这样在装饰类外再套上另一个装饰者的话,内层装饰者定义的新方法仍然可以访问。这样不用担心新创建的方法无法访问了。

var Bicycle = new Interface('Bicycle', ['assemble', 'wash', 'getPrice']);
/* 自行车实例. */
var AcmeComfortCruiser = function() { };// implements Bicycle
AcmeComfortCruiser.prototype = {
    assemble: function() {
    },
    wash: function() {
    },
    getPrice: function() {
        return 399.00;
    }
};
var BicycleDecorator = function(bicycle) { // implements Bicycle
    this.bicycle = bicycle;
    this.interface = Bicycle;
    //这处会自动循环,通过另一种方式代替方法的调用,见最后    outerloop: for(var key in this.bicycle) {
        // Ensure that the property is a function.
        if(typeof this.bicycle[key] !== 'function') {
            continue outerloop;
        }
        for(var i = 0, len = this.interface.methods.length; i < len; i++) {
            if(key === this.interface.methods[i]) {
                continue outerloop;
            }
        }
        // Add the new method.
        var that = this;
        (function(methodName) {
            that[methodName] = function() {
                return that.bicycle[methodName]();
            };
        })(key);
    }
}
BicycleDecorator.prototype = {
    assemble: function() {
        return this.bicycle.assemble();
    },
    wash: function() {
        return this.bicycle.wash();
    },
    getPrice: function() {
        console.log('4');
        return this.bicycle.getPrice();
    }
};
var HeadlightDecorator = function(bicycle) { // implements Bicycle
    HeadlightDecorator.superclass.constructor.call(this, bicycle);
}
extend(HeadlightDecorator, BicycleDecorator); // Extend the superclass.
HeadlightDecorator.prototype.assemble = function() {
    return this.bicycle.assemble() + ' Attach headlight to handlebars.';
};
HeadlightDecorator.prototype.getPrice = function() {
    console.log('3');
    return this.bicycle.getPrice() + 15.00;
};
var TaillightDecorator = function(bicycle) { // implements Bicycle
    TaillightDecorator.superclass.constructor.call(this, bicycle);
}
extend(TaillightDecorator, BicycleDecorator); // Extend the superclass.
TaillightDecorator.prototype.assemble = function() {
    return this.bicycle.assemble() + ' Attach taillight to the seat post.';
};
TaillightDecorator.prototype.getPrice = function() {
    console.log('2');
    return this.bicycle.getPrice() + 9.00;
};
TaillightDecorator.prototype.ringBell = function() {
    console.log('1');
    return 'Bell rung.';
};
var c = new AcmeComfortCruiser();
c = new TaillightDecorator(c);
c = new HeadlightDecorator(c);
console.log(c.ringBell());//无论什么顺序都会调用console.log(c.getPrice());//423

有些时候装饰者的应用顺序很重要,但在理想情况下,装饰者应该能以一种完全与顺序无关的方式创建。如果必须要以某种顺序调用,可以结合工厂一般可以办到。某些装饰者修改组件方法的方式决定了它们需要最先或最后被应用,在此情况下工厂的作用就尤为重要。

函数装饰者

也可以用装饰者来装饰函数,通过把函数当作参数传递。在PYTHON语言中这是一个核心应用。它对函数的输出应用某种格式或执行某种转换方面非常有用。文章来源地址https://www.toymoban.com/news/detail-816215.html

到了这里,关于javascript设计模式-装饰者的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JavaScript 设计模式之组合模式

    在我们日常中肯呢个会将一个表单用这种模式来创建 先写一个基类,再继承该基类 首先我们创建一个基类 定义 接下来创建一个容器 注意,这里的 show 方法就是用来将所有的 dom 追加到页面上 下面创建一系列的 form 相关 item 及一些dom 使用  假使页面中存在 dom  js 效果 组合模

    2024年02月22日
    浏览(40)
  • javaScript设计模式-工厂

    它的好处是消除对象间的耦合度,在派生子类时提供了更大的灵活性。但盲目的把普通的构造函数扔在一边,并不值得提倡。如果要采一不可能另外换用一个类,或都不需要在运行期间在一系列可互换的类中进行选择,就不应该使用。这样在后期代码重构时还有机会使用。

    2024年01月20日
    浏览(44)
  • javaScript设计模式-单例

    确保一个类只有一个实例,并提供全局访问点。 这个模式有三种不同的实现方式,每种都合理。但各有各的用处,其实用static类也可以实现相似的功能,不同的是单例是使用再创建,static是JVM加载时就创建。 单例提供了将代码组织为一个逻辑单元的手段,它有许多用途:可

    2024年01月19日
    浏览(31)
  • JavaScript设计模式详解

    JavaScript设计模式是解决软件设计中常见问题的可重复使用的解决方案。本博客将深入探讨JavaScript设计模式的各个方面,包括设计模式的类别、创建型、结构型、行为型、并发型和架构型设计模式。 设计模式是一种在软件设计中解决常见问题的可重用解决方案。它们是经过验

    2024年01月19日
    浏览(39)
  • javascript设计模式-组合

    组合模式 是一种专为创建WEB上的动态用户界面而量身定制的模式。使用它,可以用一条命令在多个对象上激发复杂或递归行为,那些复杂行为被委托给各个对象。前提是每个对象必须实现相同的接口。接口检查越严格,其稳定性越高。 可以用同样的方法处理对象的集合与其

    2024年01月21日
    浏览(33)
  • JavaScript 设计模式之享元模式

    将一部分共用的方法提取出来作为公用的模块 享元模式的应用目的是为了提高程序的执行效率与系统的性能。因此在大型系统开发中应用是比较广泛的,有时可以发生质的改变。它可以避免程序中的数据重复。有时系统内存在大量对象,会造成大量存占用,所以应用享元模式

    2024年02月22日
    浏览(35)
  • javascript设计模式-责任链

    责任链 可以用来消除请求的发送者和接收者之间的耦合,这是通过实现一个由隐式地对请求进行处理的对象组成的链而做到的。链中的每个对象可以处理请求,也可以将其传给下一个对象。JS内部就使用了这种模式来处一事件捕获和冒泡问题。一般的结构如下: 发送者知道链

    2024年01月23日
    浏览(29)
  • javascript设计模式-应用示例

    有些时候为了适应没的场景,有些代码没必要每次调用时都进行一次环境判断,所以可以memoizing技术动态改写运行中代码的实现。 发起多个请求,程序会自动缓存,并通过setTimeOut重复调用。 这个例子充分应用了通道方法,利用此模式应该可以做到AOP的功能。

    2024年01月23日
    浏览(30)
  • JavaScript中的设计模式

    本文作者为 360 奇舞团前端开发工程师 JavaScript 设计模式是编程世界的智慧结晶,提供了解决常见问题的优秀方案。无论你是初学者还是经验丰富的开发者,掌握这些模式都能让你的代码更清晰、更灵活。本文将为你介绍一些常见的设计模式,帮助你提高代码质量,构建更可

    2024年02月21日
    浏览(31)
  • JavaScript设计模式(五)——发布订阅模式、桥接模式、组合模式

    个人简介 👀 个人主页: 前端杂货铺 🙋‍♂️ 学习方向: 主攻前端方向,正逐渐往全干发展 📃 个人状态: 研发工程师,现效力于中国工业软件事业 🚀 人生格言: 积跬步至千里,积小流成江海 🥇 推荐学习:🍍前端面试宝典 🍉Vue2 🍋Vue3 🍓Vue2/3项目实战 🥝Node.js🍒

    2024年02月09日
    浏览(29)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包