在编写JS和汇编代码的过程中,使用一定的设计模式可以让我们的代码更加优雅灵活。 下面,笔者将结合redux中的subscribe、ES6中的class、vue中的$dispatch、jquery中的on/off,简单介绍一下设计模式在这些库、语法、框架中的使用。 设计模式解决问题设计模式并不是很玄乎的知识。很多同学在写JS代码的时候,已经不经意地用到了很多设计模式。笔者认为讨论设计模式的抽象与算法中冒泡排序的抽象是一样的,都是为了描述一个常用的JS模式。通过研究这种模式,让模式指导我们的代码结构和JS算法。 一些常见设计模式的概述 observer【观察者模式】 根据状态变化主动触发观察者队列和hashMap的回调行为 一个简单的观察者模式代码实践类StateTracker{构造函数(){this.observers=[];this.internamState=10;}//改变内部状态,触发状态观察者列表change(val){this.internamState=val;this.observers.forEach(observer=>observer(val));}registerObserver(ObserverFn){this.obserers.push(ObserverFn)}} publish/subscribe【订阅发布方式】 将hashMap的topic/callback形式存储在代码模块的共享访问空间中。 添加on/off/trigger等接口,实现挂载、移除、触发等动作。 一个简单的订阅-发布模式代码实践classPubSubHandler{constructor(){this.eventPool={};}//removeoff(topicName){deletethis.observers[topicName]}//发布触发器(topicName,...args){this.eventPool[topicName]&&this.eventPool[topicName].forEach(callback=>callback(...参数));}//订阅(topicName,callback){lettopic=this.eventPool[topicName];if(!topic){this.eventPool[topicName]=[]}this.eventPool[topicName].push(callback)}} singleton[单例模式] 构造函数只有一个实例。一般通过闭包来存储内部实例,通过接口访问内部实例。var单例=()=>{var实例;varcreateInstance=()=>{this.a=1;这个.b=2;}return{getInstance:()=>{if(!instance){instance=createInstance();}返回实例;}}}vartest=singleton();test.getInstance()==test.getInstance()//true 装饰器混合模式 这种模式是为原有对象装饰更多的行为,并保持变量名不变。用过ES7的@decorator或者python等语言的应该对装饰器不陌生。函数装饰器(sourceObj,decortorFn){decortorFn(sourceObj);返回sourceObj}vard={a:1};//d变成{a:1,b:1}d=decorator(d,(d)=>{d.b=1}); mixin混音模式 这种模式有点类似于装饰器,只是它的功能更垂直。是在原有对象上添加和覆盖对象的行为。与extends、Object.assign等方法相比,mixin模式的表现力更强。mixin模式不能一概而论,根据不同的数据类型可能会有不同的mixin策略,比如vue.mixinclassStateTracker{constructor(){this.raw={a:1,b:2}}mixin(obj){Object.assign(this.raw,obj)} 作者就暂时先介绍这么多设计模式,然后再针对常用的框架、语法、库等讲解这些设计模式的应用。 redux中的观察者模式varstore=createStore(reducer,initialState);//注册reduxstore,保存在nextListeners数组中vartest=store.subscribe(()=>{console.log('Iregistered!')});//注销监听test.unsubscribe(); 在jquery中发布/订阅$(document).on('hello',()=>{console.log('hello')})$(document).trigger('hello');$(document).off('hello') react-redux中装饰器模式实践//装饰器@connect(state=>state)classContainerextendsComponent{render(){returnJSON.stringify(this.props)}}
