Intent:
Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn't otherwise because of incompatible interfaces. 用于不同接口之间的转换。
Structure:
A class adapters uses multiple inheritance to adapter one interface to another.
An object adapter relies on object compositions:
Participants:
Target - defines the domain-specific interface that Client uses.
Client - collaborates with objects confirming to the Target interface.
Adaptee - defines an existing interface that needs adapting.
Adapter - adapters the interface of Adaptee to the Target interface.
Collaborations:
Clients call operations on an Adapter instance. In turn, the adapter calls Adaptee operations that carry out the request.
Consequences:
Class and object adapters have different trade-offs. A class Adapter //基于类继承模式的和基于组合对象模式各有千秋。
- adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter won't work when we want to adapt a class and all its subclass. //由于适配器同时实现了Target接口与Adaptee接口,这种模式不能适用于适配多个Adaptees,即使具有继承关系。
- lets Adapter override some of Adaptee's behavior, since Adapter is a subclass of Adaptee.// Adapter可以修改Adaptee的实现,这是优点。
- introduces only one object, and no additional pointer indirection is needed to get to the adaptee. //一个adapter,同一个adaptee!
An object adapter
- lets a single Adapter work with many Adaptees - that is, the Adaptee itself and all of its subclasses(if any). The Adapter can also add functionality to all Adaptees at once. //比较灵活嘛,又一次说明组合比继承根据灵活度。
- makes it harder to override Adaptee behavior. It will require subclassing Adaptee and makeing Adapter refer to the subclass rather than the Adaptee itself. //harder说明是可以的,比如Decorator模式。
Here are other issues to consider when using the Adapter pattern://值得思索
1. How much adapting does Adapter do? Adapters vary in the amount of work they do to adapt Adaptee to the Target interface. There is a spectrum of possible work, from simple interface conversion - for example, changing the names of operations - to supporting an entirely different set of operations. The amount of work Adapter does depends on how similar the Target interface is to Adaptee's.//Adaptee与Target区别越大,adapter的活越多,可以想法从这里减少工作量。
2. Pluggable adapters. A class is more reusable when you minimize the assumptions other classes must make to use it. By building interface adaptation into a class, you eliminate the assumption that other classes see the same interface. Put another way, interface adaptation lets us incorporate our class into existing systems that might expect different inferfaces to the class. Object-Works/Smaltalk uses the term pluggable adapter to describe classes with built-in interface adaptation. // 尽量缩小接口行为,做成可插拔的适配器模型。android 中的Adapter就是如此。
Consider a TreeDisplay widget that can display tree structures graphically. If this were a special-purpose widget for use in just one application, then we might require the objects that it displays to have a specific interface; that is , all must descend from a Tree abstract class. But if we wanted to make TreeDisplay more reusable(say we wanted to make it part of a toolkit of useful widgets), then that requirement would be unreasonable. Applications will define their own classes for tree structures. They shouldn't be forced to use out Tree abstract class. Different tree structures will have different interfaces.
In a directory hierarchy, for example, children might be accessed with a GetSubdirectories operation, whereas in an inheritance hierarchy, the corresponding operation might be called GetSubclasses. A reusable TreeDisplay widget must be able to display both kinds of hierarchies even if they use different interfaces. In other words, the TreeDisplay should have interface adaptation built into it.
We'll look at different ways to build interface adaptation into classes in the Implementation section.
3. Using two-way adapters to provide transparency. A potential problem with adapters is that they aren't transparent to all clients. An adpated object no longer conforms to the Adaptee interface, so it can't be used as is wherever an Adaptee object can. Two-way adapters can provide such transparency. Specifically, they're useful when two different clients need to view an object differently.