JS设计模式:结构型

JS设计模式:结构型

(一)外观模式(Facade)

为一组复杂的子系统接口提供一个更高级的统一接口,通过这个接口使得对子系统接口的访问更容易。在Javascript中有时也会用于对底层结构兼容性做统一封装来简化用户使用。

关键词:简化封装

外观模式是对接口方法的外层包装,以供上层代码调用,不需了解对象内部实现。多用于代码库封装功能。

  • 简化底层接口复杂性
  • 解决浏览器兼容性问题

示例:

// 封装新代码库功能,简化底层代码
var myCode = {
	// 设置元素的属性
	css: function(id, key, value) {
		document.getElementById(id).style[key] = value;
	}
}

// 简化后调用
myCode.css('myId', 'color', '#333');
// 封装绑定事件兼容不同浏览器
function addEvent(dom, type, fn) {
	if (dom.addEventListener) {
		dom.addEventListener(type, fn, false);
	} else if (dom.attachEvent) {
		dom.attachEvent('on' + type, fn);
	} else {
		dom['on' + type] = fn;
	}
}

(二)适配器模式(Adapter)

将一个类(对象)的接口(方法或属性)转化成另外一个接口,以满足用户需求,使类(对象)之间接口的不兼容问题通过适配器得以解决。

关键词:重组封装

Javascript中的适配器,更多应用在对象之间,为了使对象可用,通常会将对象拆分并重新包装。

适配器模式对原有对象进行拓展,是对对象内部结构的重组,需了解其自身结构。

  • 适配异类框架(适配两个代码库)
  • 参数适配器(考虑参数顺序及完整性,写插件时对于参数的配置)
  • 数据适配器(服务端数据适配,解决前后端的数据依赖)

示例:

// 参数适配
function myFn(obj) {
	var _adapter = {
		argument1: '参数1及默认值',
		argument2: '参数2及默认值'
	};
	for (var i in _adapter) {
		_adapter[i] = obj[i] || _adapter[i];
	}
	// do things
}

// 经常使用的还是参数适配器和数据适配器
// eg. 如上写一个参数适配插件配置
// eg. 如商品规格在前端展示列表与后端返回数据不同,需要进行数据适配器处理再渲染。

外观模式与适配器模式的区别:二者都解决了对象之间的耦合度,但适配器模式需要了解适配对象的内部结构,而外观模式不需要。

(三)代理模式(Proxy)

由于一个对象不能直接引用另一个对象,所以需要通过代理对象在这两个对象之间起到中介的作用。

一般代理对象有 img script link,主要涉及跨域的一些知识。

(四)装饰者模式(Decorator)

在不改变原对象的基础上,通过对其进行包装拓展(添加属性或方法)使原有对象可以满足用户的更复杂需求。

关键词:封装拓展

装饰者模式对原有对象进行拓展,是在外部进行了一次封装拓展,不需了解对象内部实现,保护原有功能完整性。

示例:

// 场景:为输入框增加新交互需求功能
var phoneInput = document.getElementById('phone_input');

phoneInput.onclick = function() {
	console.log('phoneInput原绑定事件');
}

// 装饰者
var decorator = function(input, fn) {
	var input = document.getElementById(input);
	if (typeof input.onclick === 'function') { // 事件源已绑定事件
		var oldClickFn = input.onclick;
		input.onclick = function() {
			oldClickFn(); // 事件源原有回调函数
			fn(); // 执行事件源新增回调
		}
	} else { // 事件源未绑定事件
		input.onclick = fn;
	}
}

// 调用
decorator('phoneInput', function(){
	console.log('给phoneInput绑定新事件');
})

适配器模式与装饰者模式的区别:适配器模式是对原有对象适配,添加的方法与原有方法功能上大致相似。但是装饰者提供的方法与原来的方法功能项是有一定区别的。再有,使用适配器时我们新的方法是要调用原来的方法,在装饰者则不需要了解对象原有的功能,并且对象原有的方法照样可以原封不动地使用。

(五)桥接模式(Bridge)

在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦。

关键词:多维解耦

桥接模式是先抽象提取共用部分,然后将实现与抽象通过桥接方式链接在一起,来实现解耦的作用,而对于多维变化也同样适用。

桥接模式最主要的特点即是将实现层(如元素绑定的事件)与抽象层(如修饰页面UI逻辑)解耦分离,使两部分可以独立变化。体现了面向对象对拓展的开放及修改的关闭原则。

示例:

// 抽象类
function AbstractClassSpeed(x, y){
       this.x = x; 
       this.y = y;
}
AbstractClassSpeed.prototype.run = function() {
	console.log('AbstractClassSpeed run')
}

function AbstractClassSpeak(word){
       this.word = word;
}
AbstractClassSpeak.prototype.say = function() {
	console.log('AbstractClassSpeak say')
}

// 桥接器
function BridgeClassPeople(x, y, word){
       this.speed = new AbstractClassSpeed(x, y);
       this.speak = new AbstractClassSpeak(word);
}
BridgeClassPeople.prototype.init = function() {
	this.speed.run();
	this.speak.say();
}

// 实例
var people = new BridgeClassPeople(10, 20, 'I say a word!');
people.init();

(六)组合模式(Composite)

又称部分-整体模式,将对象组合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

关键词:多层次组合 表单

组合对象类通过继承同一个父类使其具有统一的方法。有时这也是对数据的分级式处理。

(七)享元模式(Flyweight)

运用共享技术有效地支持大量的细粒度的对象,避免对象间拥有相同内容造成多余的开销。

关键词:共享分离 分页

享元模式通过合理提取共有的数据和方法,提高程序的执行效率与系统的性能。

一般用于大型系统开发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值