js中部分常见设计模式介绍

设计模式

设计模式的概念 :
代码书写经验,为了应对各种场景,经过前人不断的总结,压缩,形成的一套又一套的代码的书写规范,形成了设计模式。针对特定问题,提出见解而有效的处理方案

比如:假设有一个空房间,我们要日复一日地往里 面放一些东西。最简单的办法当然是把这些东西 直接扔进去,但是时间久了,就会发现很难从这 个房子里找到自己想要的东西,要调整某几样东 西的位置也不容易。所以在房间里做一些柜子也 许是个更好的选择,虽然柜子会增加我们的成 本,但它可以在维护阶段为我们带来好处。使用 这些柜子存放东西的规则,或许就是一种模式

设计模式的原则 :
设计模式的原则是“找出 程序中变化的地方,并将变化封装起来”,它的关键是意图,而不是结构。
单例模式:
定义:一个类只返回一个实例,一旦创建再次调用就直接返回
如何让一个类只有一个实例,并且能够多次访问
方案一 : 修改系统默认使用

		function Fn(){
			// 将来给Fn身上添加一个属性,这个属性为对象,但是又不能每次都添加
			// 只有第一次添加,之后都不再添加
			// 判断,如果是第一次,意味着之前没有添加过,默认是undefined(转成布尔是false),如果不是第一次,意味着添加过,那么就是对象,直接跳过,执行下面的语句
			if(!Fn.obj){
				Fn.obj = {};
			}
			Fn.obj.sayHello = "hello";
			return Fn.obj;
		}
		var f1 = new Fn();
		var f2 = new Fn();
		
		console.log(f1);
		console.log(f2);
		
		console.log(f1 === f2); //t

在这里插入图片描述
方案二: 利用封装实现

// 需要一个构造函数
			function Person(){}
			// 封装一个单例模式的调用方式
			var f = (function(){
				var instance;  //等同于第一个写法中的Fn.obj
				return function(){
					// 如果没有instance这个实例对象,就创建一个,如果有了则不再创建,直接跳过,执行下一条语句return
					if(!instance){
					// 将构造函数赋于instance这个对象
						instance = new Person();
					}
					return instance;
				}
			})(); //匿名函数直接自动执行了,得到第一个return后的函数赋于f
			
		var p1 = f();
		var p2 = f(); //f执行后得到第二个return后的instance
		console.log(p1);
		console.log(p2);
		console.log(p1 === p2); //t

在这里插入图片描述
组合模式:
定义: 把几个构造函数的入口函数组合在一起,然后使用一个’遥控器’进行统一调用
简单的组合模式实现:

// 先准备一些需要批量执行的功能
		class GoHome{
			init(){
				console.log("到家了,开门");
			}
		}
		class OpenComputer{
			init(){
				console.log("开电脑");
			}
		}
		class OpenMusic{
			init(){
				console.log("开音乐");
			}
		}
		
		// 组合器,用来组合功能
		class Comb{
			constructor(){
				// 准备容器,用来放置将来组合起来的功能
				this.skills = [];
			}
			// 用来组合的功能,接收要组合的对象
			add(task){
				// 向容器中填入,将来准备批量使用的对象
				this.skill.push(task);
			}
			// 用来批量执行的功能
			action(){
				// 拿到容器中的对象,才能批量执行
				// forEach遍历容器中的对象,只需要拿到数据,所以这里只需要第一个参数,当参数只有一个时,箭头函数的小阔号可以省略
				this.skills.forEach(val = >{
					var.init();
				});
			}
		}
		
		// 创建一个组合器
		var c = new Comb();
		
		// 提前将,将来要批量操作的对象,组合起来
		c.add(new GoHome());
		c.add(new OpenComputer());
		c.add(new OpenMusic());
		
		// 执行组合器的启动功能
		c.action();
		// 在内部会自动执行所有已经组合起来的对象的功能

观察者模式:
观察者模式也叫发布订阅者模式
定义: 以观察的角度,发现对应的状况处理问题

比如在上学的时候班主任,或者是学校的教导主任等,经常喜欢在暗地里观察学生的状态,不同的状态,不同的人可能会给出不同的处理,但这不同的处理又可以同时存在

function Stu(n){
				this.name = n;
				this.type = function(){
					if(Math.random()>0.5){
						return "学习";
					}else{
						return "睡觉";
					}
				}
			}
			
			function Teac(n){
				this.name = n;
				this.listen = function(t,sn){
					if(t == "学习"){
						console.log(`${t},${sn}是好学生`);
					}else{
						console.log(`${t},给${sn}一个大过`);
					}
				}
			}	
			
			function Teac2(n){
				this.name = n;
				this.listen = function(t,sn){
					if(t == "学习"){
						console.log(`嗯嗯.....`);
					}else{
						console.log(`给${sn}一个警告`);
					}
				}
			}		
				
			var s = new Stu("张三");
			var t = s.type();
			var t1 = new Teac("班主任");
			t1.listen(t,s.name);
			
			var t2 = new Teac2("教导主任");
			t2.listen(t,s.name);
			

在这里插入图片描述
策略模式:
定义: 给出多个计划,当将来发生某种状态,执行对应的计划
类似于: 选择语句的执行

如:promise中的then和catch状态,根据这两种不同的状态做出不同的操作

var p = new Promise(function(a,b){
			// 异步的程序要放在这里(正在执行)
			setTimeout(()=>{
			// a就是在then中的第一个回调函数,表示成功要做的事情
				// console.log(1);
				a();
			},Math.random()*1000);
			
			setTimeout(()=>{
			// b就是在catch中的第一个回调函数,表示失败要做的事情
				// console.log(2);
				b();
			},Math.random()*1000);
			
		});
		var p2 = p.then(function(){
			// 成功的预置函数
			console.log("成功");
			// 假设这里又返回了一个promise对象(p1),那么可以连缀执行
			return p1;
			// 那么在当前then的执行身上就可以拿到promise对象p1(用p2来保存p1)
		});
		
		// p1执行成功之后要做的时
		p2.then(function(){
			
		})
		// promise将原来异步中的回调函数的嵌套变成连缀执行,用这种方式解决回调地狱的写法
		p.catch(function(){
			// 失败的预置函数
			console.log("失败");
		});

MVC模式:
定义: MVC的全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种软件设计典范。它是用一种业务逻辑、数据与界面显示分离的方法来组织代码,将众多的业务逻辑聚集到一个部件里面,在需要改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑,达到减少编码的时间。
使用的MVC的目的: 在于将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。

// MVC模式:
		// 	M:model数据
		// 	V:view视图
		//  C:ctrl控制器
		
		// 创建模型,管理多个数据
		class Model{
			model1(){
				return "hello";
			}
			model2(){
				return "beautiful";
			}
			model3(){
				return "world";
			}
		}
		
		// 创建视图,管理多种渲染方式
		class View{
			view1(data){
				console.log(data);
			}
			view2(data){
				document.write(data);
			}
			view3(data){
				alert(data);
			}
		}
		
		// 创建控制器,设定对应的指令
		class Ctrl{
			constructor(){
				// 初始化模型和视图
				this.m = new Model();
				this.v = new View();
			}
			// 在指令中,可以读取对应的数据,放到对应的视图中
			ctrl1(){
				var data = this.m.model1();
				this.v.view1(data);
			}
			ctrl2(){
				var data = this.m.model3();
				this.v.view2(data);
			}
		}
		
		var c = new Ctrl();
		c.ctrl1();
		c.ctrl2();

在这里插入图片描述
装饰者模式:
定义: 以动态地给某个对象添加一些额外的职责,而不会影响从这个类中派生的其他对象。是一种“即用即付”的方式,能够在不改变对 象自身的基础上,在程序运行期间给对象动态地 添加职责

function Person() {}
		
		Person.prototype.skill = function() {
		    console.log('数学');
		};
		
		// 装饰器,还会音乐
		function MusicDecorator(person) {
		    this.person = person;
		}
		
		MusicDecorator.prototype.skill = function() {
		    this.person.skill();
		    console.log('音乐');
		};
		
		// 装饰器,还会跑步
		function RunDecorator(person) {
		    this.person = person;
		}
		
		RunDecorator.prototype.skill = function() {
		    this.person.skill();
		    console.log('跑步');
		};
		
		var person = new Person();
		
		// 装饰一下
		var person1 = new MusicDecorator(person);
		var person2 = new RunDecorator(person1);
		
		person.skill(); // 数学
		person1.skill(); // 数学 音乐 
		person2.skill(); // 数学 音乐 跑步

总结: 所有的设计模式的共同目标都是:高内聚,低耦合

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值