javascript设计模式及应用场景
栏目: JavaScript · 发布时间: 6年前
内容简介:这里花几分钟时间来讲解几个设计模式以及它们的应用场景。可以帮助你在平时开发时把设计模式用起来废话不多说,直接上demo目前浏览器不支持装饰器模式,如果想要让这段代码跑起来的话,需要依赖babel的一个插件:babel-plugin-transform-decorators-legacy
这里花几分钟时间来讲解几个 设计模式 以及它们的应用场景。可以帮助你在平时开发时把设计模式用起来
- 装饰器模式
- 迭代器模式
- 发布订阅模式
- 工厂模式
- 单例模式
- 代理模式
- 外观模式
废话不多说,直接上demo
装饰器模式
装饰器DEMO
<!--index.js-->
function decoratorHoc(target){
target.customerName = 'xuqiang';
}
@decoratorHoc
class Person{}
console.log(Person.customerName);
复制代码
装饰器疑问 ️
- decoratorHoc是个函数,为何支持@decoratorHoc?不要把这个当作理所当然。可以试下把代码拷入vscode,然后code runner,发现报了这段错
目前浏览器不支持装饰器模式,如果想要让这段代码跑起来的话,需要依赖babel的一个插件:babel-plugin-transform-decorators-legacy
那么下面三步来把babel环境搞一下
- 安装全局babel
<!--在当前index.js目录下--> yarn add babel-cli -g yarn add babel-plugin-transform-decorators-legacy 复制代码
- 配置.babelrc
<!--在当前index.js目录下新建.babelrc文件,内容如下-->
{
plugins: ['transform-decorators-legacy']
}
复制代码
- 编译index.js
<!--在当前index.js目录下--> babel index.js --out-file compiled.js 复制代码
这里把index.js编译为了compiled.js。然后code runner compiled.js,发现日志输出了"xuqiang"
至此你就实现了装饰器decoratorHoc
装饰器模式应用场景
装饰器模式可以说是非常方便地扩展了一个对象。那么平时开发中是不是有几类代码跟装饰器模式很相似
- react的高阶组件
- dva的@connect
这里就举两个例子,更多场景需要你自己去发现了
迭代器模式
迭代一个对象,就可以称为是迭代器,下面从es6的迭代器来讲解下
for-of遍历json
这是一个es6的自定义迭代器DEMO,讲解如何写一个迭代器来遍历普通对象,因为遍历数组内置已经支持了
let obj = {
name: 'xuqiang',
age: 20,
[Symbol.iterator]: () => {
let props = Object.keys(obj), i = props.length;
return {
next(){
if(i > 0){
i = i - 1;
return {
value: obj[props[props.length - i - 1]],
done: false
};
}else{
return {
value: '',
done: true
};
}
}
};
}
}
for(let prop of obj){
console.log(prop);
}
复制代码
code runner发现可以正确遍历一个Object了
发布订阅模式
发布订阅的场景
用一个老生常谈的场景先来解释下发布订阅,那就是学生时代的订牛奶,先来整理下需求
- 有一个工厂,有一个let products = {},有一种属性叫做牛奶。此属性对应一个数组,数组存储每个订奶牛人的数据。
- 工厂有一个定时器,每天早上8点开始遍历products,进行牛奶派发
- 有很多消费者,向工厂订牛奶
需求整理清楚了,下面用个DEMO来实现下
// 发布订阅模式
// 发布订阅模式
class Puber{
constructor(name){
this.name = name;
this.products = {};
this.startInterval();
}
startInterval(){
setInterval(() => {
for(let prop in this.products){
if(this.products.hasOwnProperty(prop)){
this.emit(prop);
}
}
}, 3000);
}
sub(evt, cb){
if(!this.products[evt]){
this.products[evt] = [];
}
this.products[evt].push(cb);
}
emit(evt){
if(this.products[evt]){
let cbs = this.products[evt];
for(let cb of cbs){
cb && cb();
}
}
}
}
class Suber{
constructor(name){
this.name = name;
this.puber = new Puber('徐强');
}
getPuber(){
console.log(`我是${this.name},我的牛奶配送员是${this.puber.name}`);
}
sub(evt, cb){
this.puber.sub(evt, cb);
}
}
let customer1 = new Suber('刘思琪');
customer1.getPuber();
customer1.sub('牛奶', () => {
console.log(`现在时间是${+new Date},牛奶送至未来科技城,收件人:刘思琪`);
});
let customer2 = new Suber('徐大佬');
customer2.getPuber();
customer2.sub('牛奶', () => {
console.log(`现在时间是${+new Date},牛奶送至空港新城,收件人:徐大佬`);
});
复制代码
发现刘思琪和徐大佬,已经成功订了牛奶,并且每天早上10点钟开始派发牛奶了。当然了,这里没有写取消订牛奶的操作,大家可以自己接着写
工厂模式
class jQuery{
constructor(name){
this.name = name;
}
}
function $(name){
return new jQuery(name);
}
let obj1 = $('xuqiang');
let obj2 = $('liusiqi');
console.log(obj1);
console.log(obj2);
复制代码
工厂模式总结
这里举例也是用的jquery,可以发现jquery的$函数就是用了工厂模式,那么工厂模式有哪些好处呢?
- 不需要自己调用new jQuery。直接用$很方便
- 类似React.createElement,屏蔽了开发者直接使用new VNode,符合开放封闭原则,VNode的实现对开发者不可见
单例模式
光是单例模式的话比较简单,感觉没什么亮点,所以这里结合装饰器模式来写一个单例模式
写一个装饰器模式+单例模式的骚操作
function getInstanceHoc(target){
target.getInstance = (() => {
let instance;
return () => {
if(!instance){
instance = new Function(`return new ${target}()`)();
}
return instance;
}
})();
}
@getInstanceHoc
class Person{
eat(){
console.log('i am eating');
}
}
let obj = Person.getInstance();
console.log(obj);
obj.eat();
let obj1 = Person.getInstance();
console.log(obj === obj1);
复制代码
code runner之后发现,obj和obj1都可以eat了,然后比较obj===obj1,发现是true,说明单例模式已经成功了
代理模式
用es6的Proxy来讲一下代理
class Vue{
constructor(data){
let _data = data;
return new Proxy(this, {
get(target, key){
return _data[key];
},
set(target, key, val){
_data[key] = val;
}
});
}
}
let obj = new Vue({
name: '徐强',
age: 20
});
console.log(obj.name);
obj.name = '刘思琪';
console.log(obj.name);
复制代码
外观模式
外观模式在jquery中很常见。在我们平时开发中感觉也很好用
function winAlert(title, message, buttons, cb){
if(cb === undefined){
cb = buttons;
buttons = null;
}
console.log(title);
console.log(message);
console.log(buttons);
console.log(cb);
}
winAlert('提示', '操作完成', ['确认', '取消'], () => {});
winAlert('提示', '操作完成', () => {});
复制代码
运行结果:
这让我想起目前业务中后端所有接口都是app/htmlGateway.do,只是version,rd等参数区别,从某种角度来说这是符合外观模式的。封闭后端api的内部实现,开放htmlGetway给前端调用
但是目前这种方式有个问题是,对于yapi,rap2等mock平台不太友好。因为api路径都是一致的,会不太好mock,也可能是因为我没有发现解决方案吧,所以觉得不太好mock
ok 这几种设计模式的demo都已经讲完了。有问题可以一起谈论。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 真实项目案例实战—【状态设计模式】使用场景
- 重学 Java 设计模式:实战模版模式「模拟爬虫各类电商商品,生成营销推广海报场景」
- 重学 Java 设计模式:实战策略模式「模拟多种营销类型优惠券,折扣金额计算策略场景」
- 重学 Java 设计模式:实战备忘录模式「模拟互联网系统上线过程中,配置文件回滚场景」
- 重学 Java 设计模式:实战观察者模式「模拟类似小客车指标摇号过程,监听消息通知用户中签场景」
- 重学 Java 设计模式:实战访问者模式「模拟家长与校长,对学生和老师的不同视角信息的访问场景」
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
C程序设计(第四版)
谭浩强 / 清华大学出版社 / 2010-6-1 / 33.00元
由谭浩强教授著、清华大学出版社出版的《C程序设计》是一本公认的学习C语言程序设计的经典教材。根据C语言的发展和计算机教学的需要,作者在《C程序设计(第三版)》的基础上进行了修订。 《C程序设计(第4版)》按照C语言的新标准C99进行介绍,所有程序都符合C99的规定,使编写程序更加规范;对C语言和程序设计的基本概念和要点讲解透彻,全面而深入;按照作者提出的“提出问题―解决问题―归纳分析”三部曲......一起来看看 《C程序设计(第四版)》 这本书的介绍吧!