广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Decorator Pattern怎么用
  • 708
分享到

Decorator Pattern怎么用

2024-04-02 19:04:59 708人浏览 薄情痞子
摘要

这篇文章给大家介绍Decorator Pattern怎么用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。装饰器模式(Decorator Pattern) 的目的非常简单,那就是:在不修

这篇文章给大家介绍Decorator Pattern怎么用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

装饰器模式(Decorator Pattern) 的目的非常简单,那就是:

在不修改原有代码的情况下增加逻辑。

这句话听起来可能有些矛盾,既然都要增加逻辑了,怎么可能不去修改原有的代码?但 SOLID  (向对象设计5大重要原则)的开放封闭原则就是在试图解决这个问题,其内容是不去改动已经写好的核心逻辑,但又能够扩充新逻辑,也就是对扩展开放,对修改关闭。

举个例子,假如产品的需求是实现一个专门在浏览器的控制台中输出文本的功能,你可能会这样做:

class Printer {   print(text) {     console.log(text);   } }  const printer = new Printer(); printer.print('something'); // something

在你满意的看着自己的成果时,产品过来说了一句:“我觉得颜色不够突出,还是把它改成黄色的吧!”

Decorator Pattern怎么用

小菜一碟!你自信的打开百度一通操作之后,把代码改成了下面这样子:

class Printer {   print(text) {     console.log(`%c${text}`,'color: yellow;');   } }

Decorator Pattern怎么用

但产品看了看又说:“这个字体有点太小了,再大一点,最好是高端大气上档次那种。

”好吧。。。“你强行控制着自己拿刀的冲动,一边琢磨多大的字体才是高端大气上档次,一边修改 print 的代码:

class Printer {   print(text) {     console.log(`%c${text}`,'color: yellow;font-size: 36px;');   } }

Decorator Pattern怎么用

这次改完你之后你心中已经满是 mmp 了,而且偷偷给产品贴了个标签:

Decorator Pattern怎么用

你无法保证这次是最后的修改,而且也可能会不只一个产品来对你指手划脚。你呆呆的看着显示器,直到电脑进入休眠模式,屏幕中映出你那张苦大仇深的脸,想着不断变得乱七八糟的  print 方法,不知道该怎么去应付那些永无休止的需求。。。

Decorator Pattern怎么用

在上面的例子中,最开始的 Printer  按照需求写出它应该要有的逻辑,那就是在控制台中输出一些文本。换句话说,当写完“在控制台中输出一些文本”这段逻辑后,就能将 Printer 结束了,因为它就是  Printer 的全部逻辑了。那在这个情况下该如何改变字体或是颜色的逻辑呢?

这时你该需要装饰器模式了。

Decorator Pattern(装饰器模式)

首先修改原来的 Printer,使它可以支持扩充样式:

class Printer {   print(text = '', style = '') {     console.log(`%c${text}`, style);   } }

之后分别创建改变字体和颜色的装饰器:

const yellowStyle = (printer) => ({   ...printer,   print: (text = '', style = '') => {     printer.print(text, `${style}color: yellow;`);   } });  const boldStyle = (printer) => ({   ...printer,   print: (text = '', style = '') => {     printer.print(text, `${style}font-weight: bold;`);   } });  const bigSizeStyle = (printer) => ({   ...printer,   print: (text = '', style = '') => {     printer.print(text, `${style}font-size: 36px;`);   } });

代码中的 yellowStyle、boldStyle 和 bigSizeStyle 分别是给 print 方法的装饰器,它们都会接收 printer,并以  printer 为基础复制出一个一样的对象出来并返回,而返回的 printer 与原来的区别是,各自 Decorator 都会为 printer 的 print  方法加上各自装饰的逻辑(例如改变字体、颜色或字号)后再调用 printer 的 print。

使用方式如下:

Decorator Pattern怎么用

只要把所有装饰的逻辑抽出来,就能够自由的搭配什么时候要输出什么样式,加入要再增加一个斜体样式,也只需要再新增一个装饰器就行了,不需要改动原来的 print  逻辑。

Decorator Pattern怎么用

不过要注意的是上面的代码只是简单的把 Object 用解构复制,如果在 prototype  上存在方法就有可能会出错,所以要深拷贝一个新对象的话,还需要另外编写逻辑:

const copyObj = (originObj) => {   const originPrototype = Object.getPrototypeOf(originObj);   let newObj = Object.create(originPrototype);       const originObjOwnProperties = Object.getOwnPropertyNames(originObj);   originObjOwnProperties.forEach((property) => {     const prototypeDesc = Object.getOwnPropertyDescriptor(originObj, property);      Object.defineProperty(newObj, property, prototypeDesc);   });      return newObj; }

然后装饰器内改使上面代码中的 copyObj,就能正确复制相同的对象了:

const yellowStyle = (printer) => {   const decorator = copyObj(printer);    decorator.print = (text = '', style = '') => {     printer.print(text, `${style}color: yellow;`);   };    return decorator; };

其他案例

因为我们用的语言是 javascript,所以没有用到类,只是简单的装饰某个方个方法,比如下面这个用来发布文章的 publishArticle:

const publishArticle = () => {   console.log('发布文章'); };

如果你想要再发布文章之后在 微博或QQ空间之类的平台上发个动态,那又该怎么处理呢?是像下面的代码这样吗?

const publishArticle = () => {   console.log('发布文章');    console.log('发 微博 动态');   console.log('发 QQ空间 动态'); };

这样显然不好!publishArticle 应该只需要发布文章的逻辑就够了!而且如果之后第三方服务平台越来越多,那 publishArticle  就会陷入一直加逻辑一直爽的情况,在明白了装饰器模式后就不能再这样做了!

所以把这个需求套上装饰器:

const publishArticle = () => {   console.log('发布文章'); };  const publishWeibo = (publish) => (...args) => {   publish(args);   console.log('发 微博 动态'); };  const publishQzone = (publish) => (...args) => {   publish(args);   console.log('发 QQ空间 动态'); };   const publishArticleAndWeiboAndQzone = publishWeibo(publishQzone(publishArticle));

前面 Printer 的例子是复制一个对象并返回,但如果是方法就不用复制了,只要确保每个装饰器都会返回一个新方法,然后会去执行被装饰的方法就行了。

装饰器模式是一种非常有用的设计模式,在项目中也会经常用到,当需求变动时,觉得某个逻辑很多余,那么直接不装饰它就行了,也不需要去修改实现逻辑的代码。每一个装饰器都做他自己的事情,与其他装饰器互不影响。

关于Decorator Pattern怎么用就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: Decorator Pattern怎么用

本文链接: https://www.lsjlt.com/news/81559.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Decorator Pattern怎么用
    这篇文章给大家介绍Decorator Pattern怎么用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。装饰器模式(Decorator Pattern) 的目的非常简单,那就是:在不修...
    99+
    2022-10-19
  • es6中语法糖Decorator怎么用
    这篇文章主要介绍了es6中语法糖Decorator怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Decorator(修饰器/装饰器)是...
    99+
    2022-10-19
  • Decorator装饰器模式怎么应用
    本篇内容主要讲解“Decorator装饰器模式怎么应用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Decorator装饰器模式怎么应用”吧! Decorat...
    99+
    2022-10-19
  • ES7中Decorator有什么用
    小编给大家分享一下ES7中Decorator有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Decorator 提供了一种...
    99+
    2022-10-19
  • pattern类compile方法怎么使用
    Pattern类的compile方法用于编译正则表达式模式,并返回一个Pattern对象。Pattern对象可以用于匹配字符串。使用...
    99+
    2023-08-11
    pattern compile
  • spring mvc中url-pattern怎么写
    这篇文章主要介绍“spring mvc中url-pattern怎么写”,在日常操作中,相信很多人在spring mvc中url-pattern怎么写问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家...
    99+
    2023-06-22
  • Python中Decorator的作用是什么
    本篇文章给大家分享的是有关Python中Decorator的作用是什么,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。首先来看一个简单的例子:# -*- co...
    99+
    2023-06-17
  • Java正则表达式中Pattern类怎么用
    本篇内容主要讲解“Java正则表达式中Pattern类怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java正则表达式中Pattern类怎么用”吧!前言在Java中,java.util.r...
    99+
    2023-06-26
  • PHP适配器模式Adapter Pattern怎么使用
    本篇内容主要讲解“PHP适配器模式Adapter Pattern怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“PHP适配器模式Adapter Pattern怎么使用”...
    99+
    2023-07-05
  • 怎么从ConnectionPool的实现看design pattern的运用
    今天就跟大家聊聊有关怎么从ConnectionPool的实现看design pattern的运用,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。从一个ConnectionPool的实现...
    99+
    2023-06-03
  • java后台怎么利用Pattern提取所需字符
    这篇文章主要讲解了“java后台怎么利用Pattern提取所需字符”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“java后台怎么利用Pattern提取所需字符”吧!写在处理问题的前面由于项目...
    99+
    2023-06-26
  • 常用的HTML5模式pattern是怎样的
    常用的HTML5模式pattern是怎样的,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。最近在做手机页面时,遇到数字输入的键盘...
    99+
    2022-10-19
  • java pattern的使用方法是什么
    Java中的Pattern类是用于定义正则表达式模式的对象。它提供了一些方法来匹配、查找和替换字符串中的文本。使用Pattern类的...
    99+
    2023-09-27
    java
  • Java中Pattern类的作用是什么
    Pattern类是Java中用于定义和匹配正则表达式的类。正则表达式是一种用于描述字符模式的语法,可以用来匹配和操作字符串。Patt...
    99+
    2023-09-05
    Java Pattern
  • chkdsk怎么用
    chkdsk是一个Windows命令行工具,用于检查和修复文件系统错误。以下是使用chkdsk命令的一些常见用法:1. 打开命令提示...
    99+
    2023-09-15
    chkdsk
  • mac怎么用
    这篇文章将为大家详细讲解有关mac怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。篇一、Mac的常用快捷键在一些 Apple 自己的键盘上,通常顶行中会有特殊按键,有音量图标、显示屏亮度图标和其他功能...
    99+
    2023-06-05
  • sitemesh怎么用
    这篇文章给大家分享的是有关sitemesh怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一,基本概念1,Sitemesh是一种页面装饰技术 : 1  :它通过过滤器(filte...
    99+
    2023-06-08
  • sed怎么用
    这篇文章给大家分享的是有关sed怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。例如,在多个系统、应用程序安装之后,我们往往需要对很多配置文件进行修改,用vi编辑器意味着耗费时间、重复劳动,而sed就可将我们...
    99+
    2023-06-09
  • Vim怎么用
    这篇文章主要为大家展示了“Vim怎么用”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Vim怎么用”这篇文章吧。安装在 Ubuntu 中可以使用如下命令来安装 Vim:sudo apt-get i...
    99+
    2023-06-13
  • memtest怎么用
    要使用Memtest进行内存测试,您需要按照以下步骤进行操作:1. 下载Memtest软件:您可以从Memtest官方网站(http...
    99+
    2023-09-17
    memtest
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作