The adapter mode can be used to adapt between the current interface and incompatible classes.
Objects that use this mode are called wrapper because they are packaging another object with a new interface.
When designing a class, you often encounter situations where some interfaces cannot be used together with existing APIs. By using the adapter, you can use these classes without directly modifying them.
Adapter features:
The adapter can be added to existing code to coordinate two different interfaces. On the surface, the adapter mode is similar to the facade mode. They all need to wrap other objects and change the interfaces they present. The difference between the two is how they change interfaces. The facade element presents a simplified interface, which does not provide additional options, and sometimes makes assumptions to facilitate the completion of common tasks. In the adapter mode, you need to convert an interface to another interface. It does not filter out certain capabilities or simplify the interface. If the expected API of the customer system is unavailable, the adapter mode is required.
An adapter can be implemented as a thin layer of code between incompatible method calls. If you have a function with three string parameters, however, the customer system has an array containing three string elements. At this time, an adapter can be used to connect the two.
Now let's look at the get method conversion between prototype library and Yui. The functions of these two functions are similar, but let's look at the differences between the two interfaces first.
//Prototype $ functionfunction $(){ var elements = new Array(); 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;}//YUI get methodYAHOO.util.Dom.get = function(el){ if(YAHOO.lang.isString(el)){ return document.getElementById("el"); } if(YAHOO.lang.isArray(el)){ var c = []; for(var i=0,len=el.length;i<len;++i){ c[c.length]=YAHOO.util.Dom.get(el[i]); } return c; } if(el){ return el; } return null;}
The implementation of the adapter is very simple:
function PrototypeToYUIAdapter(){ return YAHOO.util.Dom.get(arguments);}function YUIToPrototypeAdapter(){ return $.apply(window,el instanceof Array?el:[el]);}
To use Yui for prototype, you only need $ = prototypetoyuiadapter. On the contrary, Yahoo. util. Dom. Get = yuitoprototypeadapter.
Email adaptation API:
Below is a replacement function, and many HTML template implementations also follow this principle:
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; }); }}
Specific implementation:
var deMail = (function(){ function request(id,type,callback){ DED.util.asyncRequest( "GET", "mail.php", function(o){ callback(o.responseText); } ); } return { getMail:function(id,callback){ request(id,‘all‘,callback); }, sendMail:function(id){ //..... }, save:function(id){ //... }, move:function(id,des){ //.... }, archive:function(id){ //... }, trash:function(id){ //... }, resportSpam:function(id){ //... }, formatMessage:function(e){ var e = e || window.event; try{ e.preventDefault() }catch(e){ e.returnValue = false; } var targrtEl = e.target || e.srcElement; var id = targrtEl.id.toString().split(‘-‘)[1]; deMail.getMail(id,function(msgObject){ var resp = eval(‘(‘+msgObject+‘)‘); var details = ‘<p>{from}‘; details+=‘{date}‘; details+=‘{message}</p>‘; $(‘message-pane‘).innerHTML = DED.util.substitute(details,resp); }) } }})()addEvent(widow,‘load‘,function(){ var threads = getElementsByClass(‘thread‘,‘a‘); for (var i=0,len=threads.length;i<len;++i) { addEvent(threads[i],‘click‘,formatMessage) }})
The program is created, but the people in other groups have used the original foomail system to implement their code. The problem is that their method requires the provision of HTML fragments, the constructor only accepts one ID, and their getmail only uses the callback function. Besides, they do not want to rewrite all the code, so we decided to have an adapter.
Next we will switch from foomail to dedmail.
After the provider and receiver are fully expected, you can intercept the logic from the provider and then convert it in a way that the receiver can understand.
Let's take a look at the code of the foomail API:
fooMail.getMail(function(text){ $(‘message-pane‘).innerHTML = text;});
Note that the getmail method uses a callback method as a parameter. When called, the callback function obtains a text section containing the sender's name, date, and content. This is not ideal, but foomail engineers don't want to modify the system at risk. We can write a simple adapter for them so that they don't have to change their original code.
var deMailtoFooMailAdapter = {};deMailtoFooMailAdapter.getMail = function(id,callback){ deMail.getMail(id,function(resp){ var resp = eval(‘(‘+resp+‘)‘); var details = ‘<p>{from}‘; details+=‘{date}‘; details+=‘{message}</p>‘; callback(DED.util.substitute(details,resp)); })}fooMail = deMailtoFooMailAdapter;
In this Code, the single object demailtofoomailadapter is used to rewrite the foomail object. The single object implements a getmail method, when this method calls a callback function, an HTML text is correctly transmitted as a parameter.
The adapter is applicable to scenarios where the interface the customer system expects is not compatible with the interface provided by the existing API. It can only be used to coordinate Syntactic differences. The two methods used by the adapter should execute similar tasks, otherwise it will not solve the problem. If the customer wants a different interface, such as an interface that is easier to use, the adapter can also be used for this purpose. Just like bridging and facade elements, by creating an adapter, you can isolate abstraction and implementation so that the two can change independently.
The benefits of the adapter can help avoid large-scale rewriting of existing client code. Its Working Mechanism is to use a new interface to encapsulate existing class interfaces, this customer program will be able to use this class that is not tailored for it, without the need for this big operation.