「趣学前端」设计模式学习与应用

简介: 用技术实现梦想,用梦想打开创意之门。今天分享设计模式学习与应用。

一、前言

我开始几年的开发中几乎没有使用过设计模式。前端常见的设计模式,我看过好几遍,模式名称记得很清楚,但是具体内容和原理,我印象很模糊。

之所以记不住,用不上,原因两点,大部分功能比较简单,开发时也就用简单的方案进行实现了;对设计模式的理解没有透彻,不会用。

我感觉自己最近有高效率学习的buff,所以试着重新理解这个知识点。


二、边学边用

之前学习新技术的时候,看一遍文档或者文章,记忆并不深刻,后来发现自己对新技术的掌握程度在于自己是否真实的实现过。也就是常说的“好记性不如烂笔头”。而且我不擅长过目不忘,我需要理解了才能更好的记忆。

对于前端设计模式的学习,我采用了知识点介绍+功能代码的模式,方便学习、理解和记忆。其中知识点介绍大部分来自我参考的文章,参考文章会列在文章底部。(都是很优秀的文章)


2.1 外观模式

2.1.1 介绍

外观模式为子系统中的一组接口提供一个统一的高层接口,使子系统更容易使用。简而言之外观设计模式就是把多个子系统中复杂逻辑进行抽象,从而提供一个更统一、更简洁、更易用的API。


2.1.2 应用场景

很多我们常用的框架和库基本都遵循了外观设计模式。我们在实际开发中复杂的功能处理比如将某些复杂逻辑抽离进行封装,对外仅提供一个API即可,也是对外观模式的应用


2.1.3 简单小实例

我把之前做的功能简化了一下分享出来。

  • 三个私有方法分别是_userBaseInfo(获取用户基础信息)、_userAddressInfo(获取用户的订单信息)、_userOrderInfo(获取用户的收货地址);
  • 对外提供的方法是getUserInfo(获取用户的购物信息);
  • 将内部的数据处理封装成一个方法提供出来,这样一个外观模式就实现了。
/** * 用户-基础信息 */const_userBaseInfo= () => {
constobj= {
name: '张三',
phone: '123456',
sex: '男',
  };
returnobj;
};
/** * 用户-收货地址信息 */const_userAddressInfo= () => {
constobj= {
province: '北京市',
city: '北京市',
region: '昌平',
  };
returnobj;
};
/** * 用户-订单信息 */const_userOrderInfo= () => {
constobj= {
orderNo: '123',
price: '129',
goodName: '帽子',
  };
returnobj;
};
/** * 用户-购物信息 */constgetUserInfo= () => {
constbaseInfo=_userBaseInfo();
constaddressInfo=_userAddressInfo();
constorderInfo=_userOrderInfo();
constobj= {
...baseInfo,
...addressInfo,
...orderInfo,
  };
returnobj;
};
constuserInfo=getUserInfo();
console.log({ userInfo }); 
// 打印结果// {//   userInfo: {//     name: '张三',//     phone: '123456',//     sex: '男',//     province: '北京市',//     city: '北京市',//     region: '昌平',//     orderNo: '123',//     price: '129',//     goodName: '帽子'//   }// }


2.2 代理模式

2.2.1 介绍

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。


2.2.2 应用场景

  • 一些内部类不想或者不能直接被外部引用,可以使用代理类作为和外部的连接;
  • 功能扩展,无需修改委托类,在代理类增加需要的功能就能实现功能扩展,比如增加消息通知、日志、缓存等。


2.2.3 简单小实例

  • 一般二手书网站提供购买和出售书籍两种交易方式;
  • 多抓鱼是我常用的二手书平台,它可以看做是一个代理服务,同时多抓鱼的配送服务使用的顺丰这种快速送货和取货的服务;
/** * 二手书网站 提供购买和出售两种交易方式 */classBookTrading {
// 购买图书buyBook(props) {
props=props?props : {};
letres='购买了'+props.amount+'本'+props.name;
console.log(res);
  }
// 出售图书recoveryBook(props) {
props=props?props : {};
letres='出售了'+props.amount+'本'+props.name;
console.log(res);
  }
}
/** * 多抓鱼二手书交易平台 */classDuozhuayuextendsBookTrading {
constructor() {
super();
  }
buy(props) {
// 购买图书this.buyBook(props);
  }
buyDelivery(props) {
// 购买图书console.log('顺丰一日送达:');
this.buyBook(props);
  }
recovery(props) {
// 出售图书this.buyBook(props);
  }
recoveryPickUp(props) {
console.log('顺丰上门取件:');
this.recoveryBook(props);
  }
}
constduozhuayu=newDuozhuayu();
duozhuayu.buy({ name: '书店日记', amount: 2 });
duozhuayu.buyDelivery({ name: '中国地理杂志', amount: 5 });
duozhuayu.recovery({ name: '乌合之众', amount: 1 });
duozhuayu.recoveryPickUp({ name: '局外人', amount: 1 });
// 打印结果// 购买了2本书店日记// 顺丰一日送达:// 购买了5本中国地理杂志// 购买了1本乌合之众// 顺丰上门取件:// 出售了1本局外人


2.3 观察者模式

2.3.1 介绍

观察者模式又称发布订阅模式(Publish/Subscribe Pattern),被观察对象(subject)维护一组观察者(observer),当被观察对象状态改变时,通过调用观察者的某个方法将这些变化通知到观察者。


2.3.2 应用场景

很多类似消息传递的场景都适用观察者模式,比如商品订阅到货提醒、招聘中的求职者和HR的通信等


2.3.3 简单小实例

以电商中商品到货提醒功能为例,这个小例子帮助我很好的理解了观察者模式。

观察者模式中,被观察者(Subject)和观察者(Observer)是必不可少的,整个使用过程都是它俩的信息置换。

被观察者Subject

  • 维护观察者列表。例子中即消费者列表。
  • 定义添加和取消观察的方法。例子中即提供给消费者添加到货提醒和取消到货提醒的功能;
  • 当监测到自身变化之后,通过调用自己的notice方法依次通知每一个有通知权限的观察者,例子中即添加了到货提醒的消费者。


观察者Observer:

  • 定义update方法,提供给被观察者调用。例子中即到货之后消费者接收的通知消息。
  • 自定义方法,实现业务逻辑。例子中即添加了到货通知的消费者实际接收到的消息内容。

流程图如下:

image.jpeg

定义观察者类

// 观察者classObserver {
constructor(name) {
this.name=name;
  }
update(info) {
// 只有添加到货通知权限的才进行到货提醒if (info.notifyType==='add') {
this.remindArrival(info.goodName);
    } elseif (info.notifyType==='cancel') {
console.log(`${this.name}取消到货提醒,不会接受到系统提醒。`);
    } else {
console.log(`${this.name}没有添加到货提醒`);
    }
  }
// 到货提醒remindArrival(info) {
console.log(`亲爱的${this.name},您关注的宝贝${info}已到货!`);
  }
}

定义被观察者类

classSubject {
constructor() {
this.observerList= [];
  }
// 订阅subscribe(observer) {
observer.notifyType='add';
this.observerList.push(observer);
  }
// 取消订阅unsubscribe(observerRemove) {
observerRemove.notifyType='cancel';
this.observerList.push(observerRemove);
  }
// 到货提醒notice(good) {
this.observerList.forEach(observer=> {
letobj= {
...good,
...observer,
      };
observer.update(obj);
    });
  }
}

实例化之后的调用

constsubject=newSubject();
constobsA=newObserver('消费者A');
constobsB=newObserver('消费者B');
constobsC=newObserver('消费者C');
// obsA obsB 添加了到货提醒subject.subscribe(obsA);
subject.subscribe(obsB);
// obsC 取消到货提醒subject.unsubscribe(obsC);
// 商品外套已到货constgoodCoat= {
goodName: '外套',
};
// 通知添加到货提醒的消费者subject.notice(goodCoat);

打印输出

亲爱的消费者A,您关注的宝贝外套已到货!

亲爱的消费者B,您关注的宝贝外套已到货!

消费者C取消到货提醒,不会接受到系统提醒。


通过打印的结果可以看出,添加到货提醒的消费者能够收到商品到货通知,取消到货提醒的消费者则不会收到通知。


三、总结

学习下来,我发现实际开发中已经应用了某些设计模式,只是当时并不知道原来这样的功能设计是某个设计模式。

即便原本不擅长的技术,通过不断学习,可以从中找了新的开发思路。

我准备找时间,翻翻自己之前的代码,试试看有没有新的开发思路或者开发方案,即便是之前的代码不能轻易动它,也可以用在下一次的需求中。


心怀热爱,向阳生长


四、参考文章




目录
相关文章
|
3天前
|
设计模式 算法 搜索推荐
后端开发中的设计模式应用与实践
在软件开发的广袤天地中,后端技术如同构筑高楼大厦的钢筋水泥,支撑起整个应用程序的骨架。本文旨在通过深入浅出的方式,探讨后端开发领域内不可或缺的设计模式,这些模式犹如精雕细琢的工具箱,能够助力开发者打造出既健壮又灵活的系统架构。从单例模式到工厂模式,从观察者模式到策略模式,每一种设计模式都蕴含着深刻的哲理与实践价值,它们不仅仅是代码的组织方式,更是解决复杂问题的智慧结晶。
|
12天前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
12天前
|
设计模式 算法 测试技术
PHP中的设计模式:策略模式的应用与实践
在软件开发的浩瀚海洋中,设计模式如同灯塔,指引着开发者们避开重复造轮子的暗礁,驶向高效、可维护的代码彼岸。今天,我们将聚焦于PHP领域中的一种重要设计模式——策略模式,探讨其原理、应用及最佳实践,揭示如何通过策略模式赋予PHP应用灵活多变的业务逻辑处理能力,让代码之美在策略的变换中熠熠生辉。
|
13天前
|
JavaScript 前端开发 API
详解队列在前端的应用,深剖JS中的事件循环Eventloop,再了解微任务和宏任务
该文章详细讲解了队列数据结构在前端开发中的应用,并深入探讨了JavaScript的事件循环机制,区分了宏任务和微任务的执行顺序及其对前端性能的影响。
|
13天前
|
前端开发 算法 JavaScript
最小堆最大堆了解吗?一文了解堆在前端中的应用
该文章详细解释了堆数据结构(特别是最小堆)的概念与性质,并提供了使用JavaScript实现最小堆的具体代码示例,包括堆的插入、删除等操作方法。
最小堆最大堆了解吗?一文了解堆在前端中的应用
|
2天前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
4天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入解析与应用
本文将详细探讨PHP中的策略模式,从基本概念到实际应用进行深入分析。通过具体代码示例和应用场景,帮助读者理解并掌握这一设计模式的使用,提升软件开发的灵活性和维护性。
|
13天前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
13天前
|
存储 前端开发 算法
太平洋大西洋水流问题如何解决?一文了解图在前端中的应用
该文章深入探讨了图数据结构的基本概念及其在前端领域的多种应用,包括图的不同表示方法(邻接矩阵与邻接表)和经典的图算法(如深度优先搜索与广度优先搜索),并通过具体实例讲解了如何使用JavaScript来解决图相关的编程问题,如太平洋大西洋水流问题。
太平洋大西洋水流问题如何解决?一文了解图在前端中的应用
|
13天前
|
JSON 前端开发 JavaScript
一文了解树在前端中的应用,掌握数据结构中树的生命线
该文章详细介绍了树这一数据结构在前端开发中的应用,包括树的基本概念、遍历方法(如深度优先遍历、广度优先遍历)以及二叉树的先序、中序、后序遍历,并通过实例代码展示了如何在JavaScript中实现这些遍历算法。此外,文章还探讨了树结构在处理JSON数据时的应用场景。
一文了解树在前端中的应用,掌握数据结构中树的生命线