开发人员都应该了解的 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 设计模式可以为复杂的问题提供解决方案,提升开发速度并提高生产率。但并不能说这些设计模式就可以让开发人员偷懒了。

如果你觉得这篇文章不错,请别忘记点个关注哦~

(0)

相关推荐

  • JavaScript 里三个点 ... 的用法

    Three dots ( - ) in JavaScript Rest Parameters 使用 rest 参数,我们可以将任意数量的参数收集到一个数组中,然后用它们做我们想做的事情. 引入了其余参 ...

  • 当设计模式遇上 Hooks

    一  前言 「设计模式」是一个老生常谈的话题,但更多是集中在面向对象语言领域,如 C++,Java 等.前端领域对于设计模式的探讨热度并不是很高,很多人觉得对于 JavaScript 这种典型的面向过 ...

  • 深入理解new运算符

    在 JavaScript 中,new 运算符创建一个用户定义的对象类型的实例或具有构造函数的内置对象的实例.创建一个对象很简单,为什么我们还要多此一举使用 new 运算符呢?它到底有什么样的魔力? 认 ...

  • 前端面试题整理——手写bind函数

    var arr = [1,2,3,4,5] console.log(arr.slice(1,4)) console.log(arr) Function.prototype.bind1 = functi ...

  • 深入解读ES6系列(一)

    前言: 哈喽小伙伴们,爱说'废'话的Z又回来了,欢迎来到Super IT曾的博客时间,我说啦这个月要带的福利,说了更的博客肯定不能水你们,要一起进步学习嘛,今天我就把我学习最经典的Blue的ES6掌握 ...

  • JavaScript函数

    JavaScript函数

  • 诚之和:代码整洁之道的方法有哪些

    这篇文章主要讲解了"代码整洁之道的方法有哪些",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"代码整洁之道的方法有哪些&qu ...

  • (1条消息) 小程序云开发全套实战教程,看完你就能做云开发了。

    本教程适合刚刚入门的小白,云开发为开发者提供完整的云端支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务 ...

  • (1条消息) 小程序云开发全套实战教程(最全)

    接触到云函数已经有一段时间了,之前一直在看api,现在自己跟着网络上的资料和视频学习,做了一个小项目,类似于豆瓣读书系列. 具体是这样的一个流程,后面会一步步的实现. 小程序扫码实现读取isbn,获取 ...

  • SEO人员,都应该关注的3种特殊外链

    对于SEO人员而言,虽然一些专家一再强调外链对于SEO的影响在逐渐的减弱,而实际上,从目前来看,现有的搜索技术排名,外链仍然是一个重要的话题. 为此,有大量的SEO人员,将尽办法去建立更多的链接,但有 ...

  • 10种常见病的常备药,医护人员都常用,建...

    10种常见病的常备药,医护人员都常用,建议收藏,有备无患! 1.支气管炎--常备药--"喷托维林氯化铵片" 2.尿路感染--常备药--"诺佛沙星胶囊" 3.慢性 ...

  • 全网最全!手机里的“开发人员选项”功能都总结在这了

    粉粉们知道吗?手机设置中的"开发人员选项"隐藏了很多功能,一起来学习一下吧. 在设置>系统>关于手机>找到版本号,连续戳他7下,直到提示已经打开开发人员选项. 第 ...

  • 9种Web开发人员必备的工具和资源

    WEB前端开发社区 2021-07-29 学习 Web 设计或 Web 开发所需的技能是你在开始Web工作的第一步,但它还涉及到一些你需要熟悉的开发工具. 今天我与你分享的这些工具资源,对学习Web ...

  • 看谁都顺眼,是一种智慧,更是一种修行

    中国古代哲学家说,你看到什么,说明你内心有什么.苏东坡年轻时与佛印一起坐禅.苏东坡说:"大师,你看我坐在这里像什么?"佛印说:"看来像一尊佛."苏东坡讥笑着说: ...

  • 这7个化痰中药,医院医护人员都在用,30...

    这7个化痰中药,医院医护人员都在用,30岁的男女,建议收藏! 1.顽痰--医护人员都在用--礞石 2.热痰--医护人员都在用--贝母 3.湿痰--医护人员都在用--半夏 4.寒痰--医护人员都在用-- ...

  • 心内科医生:高血压患者都应该做的七种检查,一定要重视

    如果把人体比作一辆汽车,高血压就像是汽车烧机油这样比较普遍的"通病",其本身只要得到控制.并不会引发太大的问题,但是这样的"通病",其实也可能预示着或者即将导致 ...

  • 作为开发人员,AI领域界分成几个层次?

    目前很多人都想要学习人工智能知识,入门人工智能行业.为了能够顺利成为人工智能行业中的一员,需要对AI领域的信息有更多的了解. 作为开发人员,AI领域界可以分成以下几个层次: 1.学术研究者.他们的工作 ...

  • 便秘者都急需知道的一种天然清肠方法

    便秘者都急需知道的一种天然清肠方法