顾名思义,外观,就是套上华丽的外衣,实际上,没有这个外衣,也是没有问题的。
why?
如果直接使用第三方的接口,一方面,接口名字可能不符合应用的业务性质,另一方面,完成一个功能,可能需要复杂的多步操作。这些都给程序的可阅读性、可维护性带来不便。
有了外观模式,我们给实现外观模式的类起个更符合业务的名字,封装复杂的操作,这样,程序就变华丽了,是不?
how?
从形式上看,facade pattern 就是一个函数,封装了复杂的操作。但是从目的上看,有外观模式的形式
what?
1 添加事件处理的函数
function addEvent(el,type,fn){
if(window.addEventListener){
el.addEventListener(type,fn,false);
}else if(window.attachEvent){
el.attachEvent(type,fn,false);
}else{
el['on'+type] = fn;
}
}
addEvent 是一个基础的外观模式。正是通过这个函数,使得在实现了绑定事件的功能的时候,调用方可以不用考虑浏览器兼容问题。(外观模式封装了复杂的操作)
2 组合相关操作
var event = {
stopPropagation:function(e){
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true;
}
},
preventDefault:function(e){
if(e.preventDefault){
e.preventDefault();
}else{
e.returnValue = false;
}
},
stopEvent:function(e){
event.stopPropagation();
event.preventDefault();
}
};
stopPropagation 和 preventDefault 往往是一起使用的,我们通过将这两个函数放在stopEvent中,这个函数具有高内聚的特点,实现统一调用。
3 修改dom 的style 属性
修改一个元素
var element = document.getElementById('content');
element.style.color = 'red';
修改3个元素
var element1 = document.getElementById('foo');
element1.style.color = 'red';
var element2 = document.getElementById('bar');
element2.style.color = 'red';
var element3 = document.getElementById('baz');
element3.style.color = 'red';
当元素多时,重复写getElementById 等,很繁琐。我们希望能像下面这样修改样式
setStyle(['foo', 'bar', 'baz'], 'color', 'red');
ok,我们实现它
function setStyle(elements, prop, val) {
for (var i = 0, len = elements.length-1; i < len; ++i) {
document.getElementById(elements[i]).style[prop] = val;
}
}
需求又发生变化,我们需要修改某个元素,3个不同的样式,怎么办?
setStyle(['foo'], 'position', 'absolute');
setStyle(['foo'], 'top', '50px');
setStyle(['foo'], 'left', '300px');
避免重复,显然我们需要再优化下外观
setCSS(['foo'], {
position: 'absolute',
top: '50px',
left: '300px'
});
function setCSS(el, styles) {
for ( var prop in styles ) {
if (!styles.hasOwnProperty(prop)) continue;
setStyle(el, prop, styles[prop]);
}
}
意识到,有重复的地方,时决定使用facade pattern 的关键。如果你经常在调用b函数后,调用a函数,这是用facade pattern ,将b和a封装起来,是个不错的注意