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

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

一、前言

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

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

我感觉自己最近有高效率学习的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取消到货提醒,不会接受到系统提醒。


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


三、总结

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

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

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


心怀热爱,向阳生长


四、参考文章




目录
相关文章
|
13天前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
23天前
|
前端开发 JavaScript 应用服务中间件
在Docker部署的前端应用中使用动态环境变量
以上步骤展示了如何在 Docker 配置过程中处理并注入环墨遁形成可执行操作流程,并确保最终用户能够无缝地与之交互而无须关心背后复杂性。
76 13
|
2月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
8月前
|
前端开发 安全 开发工具
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
396 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
7月前
|
人工智能 前端开发 JavaScript
AI程序员:通义灵码 2.0应用VScode前端开发深度体验
AI程序员:通义灵码 2.0应用VScode前端开发深度体验,在软件开发领域,人工智能技术的融入正深刻改变着程序员的工作方式。通义灵码 2.0 作为一款先进的 AI 编程助手,与广受欢迎的代码编辑器 Visual Studio Code(VScode)相结合,为前端开发带来了全新的可能性。本文将详细分享通义灵码 2.0 在 VScode 前端开发环境中的深度使用体验。
1102 2
AI程序员:通义灵码 2.0应用VScode前端开发深度体验
|
8月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
459 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
8月前
|
人工智能 前端开发 JavaScript
详解智能编码在前端研发的创新应用
接下来,人与智能体的交互将变得更为紧密,比如 N 年以后是否可以逐渐过渡。这个逐渐过渡的过程实际上是温和的,从依赖人类到依赖超大规模算力的转变,可能会取代我们的一些职责。这不仅仅是简单的叠加关系。对于AI和超大规模算力,这是否意味着我们可以大幅度提升软件质量,是否可以缩短研发周期并提高效率,还有创造出更优质的软件并持续发展,这无疑是肯定的。
436 25
|
8月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
184 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
Dart 前端开发 架构师
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
【01】vs-code如何配置flutter环境-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈-供大大的学习提升
440 26
|
8月前
|
人工智能 前端开发 JavaScript
智能编码在前端研发的创新应用
在前端开发领域,智能编码技术正引领一场变革,通过大模型的强大能力将自然语言需求直接转化为高效、可靠的代码实现。
312 10