2.JavaScript中的设计模式——基础的三种

JavaScript中的设计模式

设计模式,是针对特定问题,给出简洁而优雅的解决方案。
Javascript中常见的设计模式有很多种:
1.单例模式
2.策略模式
3.代理模式
4.迭代器模式
5.发布-订阅模式
6.命令模式
7.组合模式
8.模板方法模式
9.享元模式
10.职责链模式
11.中介者模式
12.装饰者模式
13.状态模式
14.适配者模式
在初学JavaScript时,先介绍三种设计常见的设计模式:

单例模式

也就是,使用一个构造函数生成的实例化对象。因为在平常的初始化构造函数时,几班是属性方法都完全相同,默认也是生成两个不同的构造函数,如此操作就会占用很多的的内存空间,降低了执行效率。
而单例模式所解决的问题就是:在同一个构造函数,能够生成同一个实例化对象。

单例模式原理:

判断这个构造函数是否使用过,如果使用过,返回之前的对象。如果没有使用过,就执行构造函数生成实例化对象。

代码实现:
	//1.创建一个构造函数,空的
	function CreatObj(){}
	//2.创建一个变量,原始数值可有可无(基本类型)
	let res=null;
	//3.创建单例模式函数
	function Singleton(){
	//	如果res中存储值为null,也就证明没执行过构造函数,可以第一次执行构造函数,将构造函数执行结果存入res
		if(res==null){
			res=new CreatObj();
		}
	//	存入构造函数的执行结果,也就是实例化对象
	//	最终返回结果是我们创建的变量
		return res;
		}
	//4.通过单例模式函数来生成实例化对象
	const obj1=Singleton();
	const obj2=Singleton();
	console.log(obj1==obj2)
	

结果:
在这里插入图片描述

组合模式

组合模式,通俗的讲就是通过一个‘遥控器’,来控制所有入口函数的执行。也就是我们能够用相同的方式去处理一个甚至多个对象。
代码实现:

先写三个构造函数,包含多个多个方法,而init()入口函数控制了构造函数中所有方法的执行。

	class A{
		constructor(){}
		// 入口函数
		init(){
			this.a1();
			this.a2();
			this.a3();
			this.a4();
		}
		// 构造函数方法
		a1(){console.log('我是a1')}
		a2(){console.log('我是a2')}
		a3(){console.log('我是a3')}
		a4(){console.log('我是a4')}
	}
	class B{
		constructor(){}
		// 入口函数
		init(){
			this.b1();
			this.b2();
		}
		// 构造函数方法
		b1(){console.log('我是b1')}
		b2(){console.log('我是b2')}
	}
	class C{
		constructor(){}
		// 入口函数
		init(){
			this.c1();
		}
		// 构造函数方法
		c1(){console.log('我是c1')}
	}

组合模式

	class Compose{
		constructor(){
			this.arr=[];
		}
		add(obj){
			this.arr.push(obj)
		}
		execute(){
			this.arr.forEach(function(item){
				item.init();
			})
		}
	}
	const comp=new Compose();
	comp.add(new A());
	comp.add(new B());
	comp.add(new C());
	comp.execute();

在组合模式的构造函数中,通过add()这个方法,将所有需要执行的构造函数的实例化对象加进数组,并在execute()方法中,循环遍历得到每一个实例化对象,并且调用其中的入口函数,从而执行所有的方法。
结果:
在这里插入图片描述

发布-订阅模式

发布-订阅模式,又被称作为,观察者模式。

官方定义

的那个一个对象的状态发生改变时,所有依赖于这个对象的相关的对象,都要发送通知,并且根据程序的需求,主动更新数据。

作用

主要是解决主体与相关对象的功能的耦合,也就是主体对象的状态改变,相关个体,数据更新。

核心代码

需要一个观察者,抽象定义为一个对象{}
需要有个属性,也称消息盒子(要执行所有的事件)
需要一个on方法,向消息盒子中添加事件
需要一个emit方法,用于发布事件
需要一个off方法,删除已经添加的方法

观察者模式的构造函数

在这里插入图片描述

观察者模式——定义on方法
// on方法
		// 将需要执行的事件,写入on方法
		// 参数一:需要执行的事件类型
		// 参数二:需要执行的事件的内容
		on(type,fun){//需要执行的操作是函数
			// 将执行类型与事件写入message消息盒子中
			// 写入之前要判断,是否有重复的内容写入
			if(!this.message[type]){
				//消息盒子中没有这个属性,就进行创建
				this.message[type]=[fun];
			}else{
				// 消息盒子中,存在这个属性,就将这个内容放进去即可
				// 向事件类型中写入需要执行的内容
				this.message[type].push(fun)
			}
		}
观察者模式——定义emit方法
// emit 执行,可能是全部执行,也可能只执行一个
		// 参数一:需要执行的类型
		// 参数二:需要执行的内容(是不确定的)
		// 所以使用 合并运算符 ...形参
		emit(type,...arr){
            if(!this.message[type]){
            	// 先判断这个类型,是否存在,不存在直接return
                return;
            }else{
            	// 类型存在,执行内容
            	// 通过双层循环,遍历两个数组,如果里面有相同的就执行这个方法
            	// 第一个数组 arr  第二个数组this.message[type]
                for(var i=0;i<arr.length;i++){
                    for(var j=0;j<this.message[type].length;j++){
                        if(arr[i]===this.message[type][j]){
                            arr[i]();
                        }
                    }
                }
            }
        }
观察者模式——定义off方法
// off执行,删除这个消息盒子中,这个类型的,符合所有执行内容
		off(type,fun){
			if(!this.message[type]){
				// 先判断有没有这个类型,要是没有,就执行return,终止之后函数的执行
				return;
			}else{
				// 有这个类型,就删除相应的类型
				// 类型以数组存储,那么循环遍历数组,删除与之相同的
				for(let i=0;i<this.message[type].length;i++){
                    if(fun===this.message[type][i]){
                        this.message[type].splice(i,1);
                        // 为了防止塌陷的操作
                        i--;
                    }
                }
			}
        }
观察者模式的添加(on)与执行(emit)
// 通过构造函数,生成实例化对象
		const obj=new Observer();
	    function baba(){
            console.log('请老爸,下午2点到学校')
        }
        function mama(){
            console.log('请老妈,上午10点到学校')
        }
        function yeye(){
            console.log('请爷爷,下午3点到学校')
        }

        function jiancha1(){
            console.log('写给老师的检查')
        }
        function jiancha2(){
            console.log('写给主任的检查')
        }
        function jiancha3(){
            console.log('写给校长的检查')
        }
        obj.on('call',baba);
        obj.on('call',mama);
        obj.on('call',yeye);
        obj.emit('call',baba,mama,yeye);

结果:在这里插入图片描述

在上面执行代码的基础上,进行off方法的执行
        obj.on('call',baba);
        obj.on('call',mama);
        obj.on('call',yeye);
        // obj.emit('call',baba,mama,yeye);
        obj.off('call',yeye);
        obj.off('call',mama);
        obj.emit('call',baba,mama,yeye)

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值