您的位置:首页 > Web前端 > JavaScript

JS设计模式之适配器模式

2013-10-15 00:22 232 查看
适配器模式用在现有接口跟不兼容的类和接口之间进行适配。用一个新的接口包装另一个对象。

适配器用在协调两个不同的接口。与门面模式的区别:

门面模式展现的是一个简化的接口,只是对代码及接口起到简化作用,不提供额外的选择。

适配器模式则是需要把一个接口转换为另外一个接口,完全保留接口,并且不会简化接口。

var clientObject={
string1:'foo',
string2:'bar',
string3:'baz'
};
function interfaceMethod(str1,str2,str3){
...
}

function clientToInterfaceAdapter(o){
interfaceMethod(o.str1,o.str2,o.str3);
}
clientToInterfaceAdapter(clientObject);


对于clientObject作为参数传递给interfaceMethod,需要使用适配器。

示例:

function $(){
var elements=[];
for(var i=0;i<arguments.length;i++){
var element=arguments[i];
if(typeof element == 'string')
element = document.getElementById(element);
if(arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}

function get(el){
if(typeof el == 'string')
return document.getElementById(el);
if({}.toString.call(el) == '[object Array]'){
var c = [];
for(var i=0,len=el.length;i<len;++i){
c[c.length]=get(el[i]);
}
return c;
}
if(el){
return el;
}
return null;
}


$函数的参数可以是一个或者多个,然而get函数只有一个,可以是个字符串、HTML元素,或者是字符串跟HTML元素组成的数组。适配这两个方法如下:

function $ToGet(){
return get(arguments);
}
function GetTo$(el){
return $.apply(window,el instanceof Array?el:[el]);
}


示例:适配电子邮件API

<html>
<head>
<script>
function $(id){
return typeof id == 'string'?document.getElementById(id):id;
}
function getElementsByClass(){
var ele = [];
function getClassElement(className,el){
var ob = [];
el = el||document;
var nodes = el.getElementsByTagName('*');
for(var i=0, len=nodes.length; i < len; i++){
if(nodes[i].className == className)
ob.push(nodes[i]);
}
return ob;
}
if(arguments.length == 1){
return getClassElement(arguments[0]);
}else{
var prev = getClassElement(arguments[0]),next = [];
for(var j = 0, length = prev.length; j < length; j++){
var r = getClassElement(arguments[1], prev[j]);
next=next.concat(r);
}
return next;
}
}
function addEvent(node, type, fn){
if(node.addEventListener){
node.addEventListener(type, fn, false);
}else if(node.attachEvent){
node.attachEvent('on'+type,fn)
}else{
node['on'+type] = fn;
}
}
var DED = {};
DED.util = {
substitute:function (s, o){
return s.replace(/{([^{}]*)}/g,function (a, b){
var r = o[b];
return typeof r == 'string' ||typeof r == 'number' ? r : a;
});
},
asyncRequest:(function(){
function handleReadyState(o, callback) {
var poll = window.setInterval(function(){
if(o&&o.readyState == 4){
window.clearInterval(poll);
if(callback)
callback(o);
}
},50);
}
var getXHR = function(){
var http;
try {
http = new XMLHttpRequest;
getXHR = function(){
return new XMLHttpRequest;
};
}
catch(e) {
var msxml = [
'MSXML2.XMLHTTP.3.0',
'MSXML2.XMLHTTP',
'Microsoft.XMLHTTP'
];
for(var i = 0, len = msxml.length; i < len; ++i){
try{
http = new ActiveXObject(msxml[i]);
getXHR = function() {
return new ActiveXObject(msxml[i]);
};
break;
}
catch(e){}
}
}
return http;
};
return function(method, uri, callback, postData){
var http = getXHR();
http.open(method, uri, true);
handleReadyState(http, callback);
http.send(postData || null);
return http;
};
})()
};
var dedMail = (function(){
function request(id, type, callback){
DED.util.asyncRequest(
'GET',
'new/index',
function(o) {
callback(o.responseText);
}
);
}
return {
getMail: function(id, callback){
request(id, 'all', callback);
},
sendMail: function(body, recipient){

},
save: function(id) {

},
move: function(id, destination){

},
archive: function(id) {

},
trash: function(id) {

},
reportSpam: function(id) {

},
formatMessage: function(e) {
var e = e || window.event;
try {
e.preventDefault();
}
catch(ex) {
e.returnValue = false;
}
var targetEl = e.target || e.srcElement;
var id = targetEl.id.toString().split('-')[1];
dedMail.getMail(id, function(msgObject) {
var resp = eval('('+msgObject+')');
var details = '<p><strong>From:</strong>{from}<br>';
details += '<strong>Sent:</strong>{date}</p>';
details += '<p><strong>Message</strong><br>';
details += '{message}</p>';
$('message-pane').innerHTML = DED.util.substitute(details, resp);
});
}
};
})();
addEvent(window, 'load', function(){
var threads = getElementsByClass('thread', 'a');
for(var i = 0, len=threads.length; i<len; i++){
addEvent(threads[i], 'click', dedMail.formatMessage);
}
});
var fooMail = {}
//fooMail.getMail方法接受两个参数 一是ID 二是回调函数 并且函数处理过 类似
//function(text){ $('message-pane').innerHTML =text;}
var dedMailToFoolMail = {};
dedMailToFoolMail.getMail = function(id, callback){
dedMail.getMail(id, function(msgObject) {
var resp = eval('('+msgObject+')');
var details = '<p><strong>From:</strong>{from}<br>';
details += '<strong>Sent:</strong>{date}</p>';
details += '<p><strong>Message</strong><br>';
details += '{message}</p>';
callback(DED.util.substitute(details, resp));
});
};
fooMail = dedMailToFoolMail;
fooMail.getMail("a",function(text){$('message-pane').innerHTML=text;});
</script>
</head>
<body>
<div id="doc">
<h1>Email Application Interface</h1>
<ul>
<li class="thread"><a class="a" href="#" id="msg-1">load
Message Sister Sonya</a></li>
<li class="thread"><a class="a" href="#" id="msg-2">load
Message Lindsey Simon</a></li>
<li class="thread"><a class="a" href="#" id="msg-3">load
Message Margaret Stoooart</a></li>
</ul>
<div id="message-pane"></div>
</div>
</body>
<script>
</script>
</html>


这个例子很明显展示出当接口类型不一样的时候,通过适配协调的方式,完成接口的通用,增加代码的复用量。

适配器在当前条件下,框架层出不穷,又不统一的情况下,避免大规模改写代码,用新的接口对不适合的接口进行包装,协调语法的差异。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: