开发人员都应该了解的 7 种 JavaScript 设计模式
云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!
开发人员将 JavaScript 设计模式作为解决问题的模板是很合适的,但并不是说这些模式可以代替开发人员的工作。
通过设计模式,我们可以将许多开发人员的经验结合起来,以优化过的方式来构造代码,从而解决我们所面对的问题。设计模式还提供了用于描述问题解决方案的通用词汇表,而不是去枯燥地描述代码的语法和语义。
JavaScript 设计模式可帮助开发人员编写出井井有条、美观且结构合理的代码。尽管设计模式很容易重用,但它们并不是要取代开发人员的工作;它们是开发人员的支持与辅助,提供了与特定应用程序无关的通用解决方案,从而尽量避免那些可能导致 Web 应用程序的开发工作出现重大问题的小漏洞。
与临时方案相比,它们消除了不必要的重复,从而缩减了代码库的整体大小,并让我们的代码更加健壮。
在本文中,我将探讨 7 种最出色和最受欢迎的 JavaScript 设计模式,这些模式主要归为以下三类:创作设计模式、结构设计模式和行为设计模式。
1、构造函数设计模式
这是一种特殊的方法,用于在分配内存后初始化新创建的对象。由于 JavaScript 一般来说是面向对象的,所以它打交道最多的就是对象。于是我打算深入研究对象构造函数。在 JavaScript 中创建新对象有三种方法可用。
以下创建构造函数设计模式的一种方法。
// 创建一个新的空对象 var newObject = {}; // 创建一个新的空对象 var newObject = Object.create(Object.prototype); var newObject = newObject();
要访问函数的属性,你需要初始化对象。
const object = new ConstructorObject();
上面的 new 关键字告诉 JavaScript,一个 constructorObject 应该充当一个构造函数。这个设计模式并不支持继承。更多细节可以参考这里。
2、原型模式
原型模式是基于原型继承的。在这种模式中,被创建的对象充当其他对象的原型。实际上,原型(prototype)是被创建的每个对象构造函数的蓝图。
示例:
var myCar= { name:"Ford Escort", brake:function(){ console.log("Stop! I am applying brakes"); } Panic : function (){ console.log ( "wait. how do you stop thuis thing?") } } // 使用 object create 实个新的例化一 car var yourCar= object.create(myCar); // 现在它就是另一个的原型了 console.log (yourCar.name);]
3、模块设计模式
模块(module)设计模式对原型模式做了一些改进。模块模式设置了不同类型的修饰符(私有和公共)。你可以创建相似的函数或属性而不会发生冲突。我们还可以灵活地公开重命名函数。这个设计模式的一个缺陷是无法覆盖(override)外部环境中创建的函数。
示例:
function AnimalContainter () { const container = []; function addAnimal (name) { container.push(name); } function getAllAnimals() { return container; } function removeAnimal(name) { const index = container.indexOf(name); if(index < 1) { throw new Error('Animal not found in container'); } container.splice(index, 1) } return { add: addAnimal, get: getAllAnimals, remove: removeAnimal } } const container = AnimalContainter(); container.add('Hen'); container.add('Goat'); container.add('Sheep'); console.log(container.get()) //Array(3) ["Hen", "Goat", "Sheep"] container.remove('Sheep') console.log(container.get()); //Array(2) ["Hen", "Goat"]
4、单例模式
在仅需要创建一个实例的情况下(例如一个数据库连接),这个模式是必需的。在这个模式中,只能在关闭连接时创建一个实例,或者在打开新实例之前必须关闭已有的实例。此模式也称为严格模式,它的一个缺点是测试时的体验很差,因为它隐藏的依赖项对象很难挑出来进行测试。
示例:
function DatabaseConnection () { let databaseInstance = null; // 追踪特定时间创建实例的数量 let count = 0; function init() { console.log(`Opening database #${count + 1}`); // 现在执行操作 } function createIntance() { if(databaseInstance == null) { databaseInstance = init(); } return databaseInstance; } function closeIntance() { console.log('closing database'); databaseInstance = null; } return { open: createIntance, close: closeIntance } } const database = DatabseConnection(); database.open(); //Open database #1 database.open(); //Open database #1 database.open(); //Open database #1 database.close(); //close database
5、工厂模式
这个模式的创新之处在于,它不需要构造函数就能创建对象。它提供了用于创建对象的通用接口,我们可以在其中指定要创建的工厂(factory)对象的类型。这样一来,我们只需指定对象,然后工厂会实例化并返回这个对象供我们使用。当对象组件设置起来很复杂,并且我们希望根据所处的环境轻松地创建不同的对象实例时,使用工厂模式就是很明智的选择。在处理许多共享相同属性的小型对象,以及创建一些需要解耦的对象时也可以使用工厂模式。
示例:
// Dealer A DealerA = {}; DealerA.title = function title() { return "Dealer A"; }; DealerA.pay = function pay(amount) { console.log( `set up configuration using username: ${this.username} and password: ${ this.password }` ); return `Payment for service ${amount} is successful using ${this.title()}`; }; //Dealer B DealerB = {}; DealerB.title = function title() { return "Dealer B"; }; DealerB.pay = function pay(amount) { console.log( `set up configuration using username: ${this.username} and password: ${this.password}` ); return `Payment for service ${amount} is successful using ${this.title()}`; }; //@param {*} DealerOption //@param {*} config function DealerFactory(DealerOption, config = {}) { const dealer = Object.create(dealerOption); Object.assign(dealer, config); return dealer; } const dealerFactory = DealerFactory(DealerA, { username: "user", password: "pass" }); console.log(dealerFactory.title()); console.log(dealerFactory.pay(12)); const dealerFactory2 = DealerFactory(DealerB, { username: "user2", password: "pass2" }); console.log(dealerFactory2.title()); console.log(dealerFactory2.pay(50));
6、观察者模式
观察者(observer)设计模式在许多对象同时与其他对象集通信的场景中用起来很方便。在观察者模式中不会在状态之间发生不必要的事件 push 和 pull;相比之下,所涉及的模块仅会修改数据的当前状态。
示例:
function Observer() { this.observerContainer = []; } Observer.prototype.subscribe = function (element) { this.observerContainer.push(element); } // 下面是从 container 中移除一个元素 Observer.prototype.unsubscribe = function (element) { const elementIndex = this.observerContainer.indexOf(element); if (elementIndex > -1) { this.observerContainer.splice(elementIndex, 1); } } /** * we notify elements added to the container by calling * each subscribed components added to our container */ Observer.prototype.notifyAll = function (element) { this.observerContainer.forEach(function (observerElement) { observerElement(element); }); }
7、命令模式
最后介绍的是命令(command)模式。命令设计模式将方法调用、操作或请求封装到单个对象中,以便我们可以自行传递方法调用。命令设计模式让我们可以从任何正在执行的命令中发出命令,并将责任委托给与之前不同的对象。这些命令以 run() 和 execute() 格式显示。
(function(){ var carManager = { // 请求的信息 requestInfo: function( model, id ){ return "The information for " + model + " with ID " + id + " is foo bar"; }, // 现在购买这个 car buyVehicle: function( model, id ){ return "You have successfully purchased Item " + id + ", a " + model; }, // 现在 arrange viewing arrangeViewing: function( model, id ){ return "You have successfully booked a viewing of " + model + " ( " + id + " ) "; } }; })();
小结
对于 JavaScript 开发人员来说,使用设计模式的好处很多。设计模式的一些主要优点包括提升项目的可维护性,还能减少开发周期中不必要的工作。JavaScript 设计模式可以为复杂的问题提供解决方案,提升开发速度并提高生产率。但并不能说这些设计模式就可以让开发人员偷懒了。
【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK
原文发布时间:2020-06-30
本文作者:Deven
本文来自:“InfoQ ”,了解相关信息可以关注“[InfoQ](https://www.infoq.cn/article/jUDjSPGGcZx7FKKhWUcc)
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript 虽火,但不要轻易去追随!
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 现在的情况是这样的:你在浏览器中输入twitter.com,然后就看到某人发了一条关于如何使用React Hooks的新推文。但是,由于某些原因,你的公司或团队尚未切换到Hooks,又或者,也许你们已经在用了,但不是以新的“流行”的那种方式用。也许你们用的是Vue.js或Angular,但是现在这些关于React Hooks的信息随处可见,甚至你会觉得在晚饭的时候,关于React Hooks的消息几乎都要出现在你的微波炉上了。 鉴于现在这种情况,你开始质疑,自己的代码库中的内容是否正确?是不是应该使用刚刚看的技术文章内容来重构这块逻辑?随着心中的疑问告一段落,你开始想象实际代码的样子。 而现在,你突然有了使用它的冲动。你联系团队负责人,或者向整个团队发消息,把这个超酷的新方法告诉他们,并建议开始使用它。 重写代码 (图片大意:这次你选的库和构建工具肯定是正确的了,真实世界:每六个月重写一遍你的前端代码) 前段时间,@ ThePracticalDev 的Twitter帐号上发表了一本不存在...
- 下一篇
WebRTC之完整搭建Jitsi Meet指南
前言 Jitsi是个优秀的WebRTC流媒体服务器,使用Java语言做开发,可以让很多Java人员也能进行流媒体开发,但是奈何国内的教程太少,官方文档更新太快,导致很多想用他的人却望而却步。 在写这篇文章之前,在搜索引擎上进行了搜索,发现没有一篇文章完整的把Jitsi Meet搭建起来并且能够多人正常音视频通话的文章 不管是论坛和QQ群经常有人问Jitsi搭建的问题,在此我就分享一篇我自己的搭建经验 注意!!!本篇使用的官方教程Manual installation(手动安装),为什么使用手动安装不是快速安装,因为我后期会在上面自定义一些功能。 jitsi官方更新的比较频繁,如果你按照本篇文章安装出现了问题,可以进入QQ群进行提问 准备工作 建议全篇的Linxu命令都使用root用户去操作,如果不是使用root,请都加sudo 一台Ubuntu18.04的服务器,拥有公网ip,最好是国外服务器,国内服务器下载依赖很慢。 一个域名,提前把域名解析到服务器的公网ip 安全组设置入网规则 tcp80,443,4443,udp:10000-20000 关闭防火墙 Ubuntu上检查防火墙状态 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- 2048小游戏-低调大师作品
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Red5直播服务器,属于Java语言的直播服务器
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7