I. Functions
Converts an interface of a class to another interface that the customer wants to resolve the mismatch between two existing interfaces. The adapter mode allows the classes that cannot work together due to incompatibility of interfaces to work together.
Ii. Structure Diagram
(1) Class Adapter
(2) Object Adapter
3., Implementation
Like many other models, the focus of learning design models is to learn the ideas of each model, rather than sticking to its specific structure and implementation. Because the mode is flexible, its implementation can be ever-changing, but the so-called changing things will never go away. The adapter mode is widely used in STL, such as function adapter and iterator adpter. They have different structures than the adapter mentioned here, but they have the same idea. For details, go to the Hou Jie website to find related articles. He spoke very well.
Iv. Sample Code
(1) Class Adapter
Namespace designpattern_adapter { // Class adaptee Class adaptee { Public: Void specialrequest (){} }; // Class target Class target { Public: Virtual void request () = 0; }; // Class Adapter Class adapter: public target, private adaptee { Public: Virtual void request () {specialrequest ();} }; } Client code: { Using namespace designpattern_adapter; Target * P = new adapter (); P-> request (); // The adaptee: specialrequest () is actually called () } |
(2) Object Adapter namespace designpattern_adapter
{ // Class adaptee Class adaptee { Public: Void specialrequest (){} }; // Class target Class target { Public: Virtual void request () = 0; }; // Class Adapter Class adapter: public target { Public: Virtual void request () {_ adaptee. specialrequest ();} PRIVATE: Adaptee _ adaptee; }; } Client code: { Using namespace designpattern_adapter; Target * P = new adapter (); P-> request (); // The adaptee: specialrequest () is actually called () } |
Vi. Instances
(1) Class adapter in STL
The adapter class in STL includes a. Stack (the corresponding adaptee is deque ). B. Queue (the corresponding adaptee is deque ). C. priority_queue (the corresponding adaptee is vector ). The following is the Stack class definition copied from <stack> in VC:
Templateclass _ Container = deque <_ ty> Class Stack {// LIFO queue implemented with a container Public: Typedef _ container container_type; Typedef typename _ container: value_type; Typedef typename _ container: size_type; Stack () : C () {// Construct with empty container } Explicit stack (const _ container & _ cont) : C (_ cont) {// Construct by copying specified container } Bool empty () const {// Test if Stack is empty Return (C. Empty ()); } Size_type size () const {// Test length of stack Return (C. Size ()); } Value_type & Top () {// Return last element of mutable Stack Return (C. Back ()); } Const value_type & Top () const {// Return last element of nonmutable Stack Return (C. Back ()); } Void push (const value_type & _ Val) {// Insert element at end C. push_back (_ Val ); } Void POP () {// Erase last element C. pop_back (); } Bool _ eq (const stack <_ ty, _ container> & _ Right) const {// Test for Stack equality Return (C = _ right. C ); } Bool _ lt (const stack <_ ty, _ container> & _ Right) const {// Test if this <_ Right for stacks Return (C <_ right. C ); } Protected: _ Container C; // The underlying container }; |
The key lies in_ Container CAll stack operations are forwarded to C for processing. (This is actually the "Object Adapter" mentioned above. Note that the class adapter in STL is inconsistent with the class adapter concept mentioned above)
Stack is easy to use as follows:
{ Int Ia [] = {1, 3, 2, 4 }; Deque ID (IA, Ia + 4 ); Stack is (ID ); } |
(2) recently read an article "generic <programming>: simplifying abnormal security code", the original from the http://www.cuj.com/experts/1812/alexandr.htm? Topic = experts. The Chinese translation is from "C ++ view 5th ". The article is absolutely first-class. The author's Code also uses the adaptor mode, which is also representative. I will summarize the problem as follows:
Problem: Assume there are several existing classes that share some common behaviors, but they are independent of each other (without a common base class ). For example:
Class T1 { Public: Void proc (){} }; Class T2 { Public: Void proc (){} }; //... |
How can we call these actions in a unified manner?
Solution 1: You will naturally think of using templates, such:
Template <class T> Void test (T) { T. Proc (); } |
It is really good, but this is only applicable to simple situations, and sometimes the situation is very complicated. For example, we cannot put the type in the template parameter!
Solution 2: The difficulty is that these classes do not have a common base class, so we create a base class and then adapt.
// Class iadaptor, abstract base class Class iadaptor { Public: Virtual void proc () = 0; }; // Class adaptor Template <class T> Class adaptor: Public iadaptor, private t // implement inheritance { Public: Virtual void proc () {T: Proc ();} }; // Call the proc function in a unified way, regardless of T1, T2, or other classes. Void test (const STD: auto_ptr & SP) { SP-> proc (); } Client code: Test (STD: auto_ptr (New Adaptor )); Test (STD: auto_ptr (New Adaptor )); |
The above example is very simple. It can be well solved by using the template function in method 1. The following is an example with a slight complexity. You can create an appropriate object based on the parameter type:
Class T1 { Public: T1 (INT ){/*...*/} Void proc (){/*...*/} }; Class T2 { Public: T2 (char ){/*...*/} Void proc (){/*...*/} }; // Class iadaptor, abstract base class Class iadaptor { Public: Virtual void proc () = 0; }; // Class adaptor Template Class adaptor: Public iadaptor, private t // implement inheritance { Public: Adaptor (int n): T (n ){} Adaptor (char C): T (c ){} Virtual void proc () {T: Proc ();} }; Class Test { Public: Test (int n): SP (New adaptor (N )){} Test (char C): SP (New adaptor (c )){} Void proc () {SP-> proc ();} PRIVATE: STD: auto_ptr sp; }; Client code: Test T1 (10 ); T1.proc (); Test T2 ('C '); T2.proc (); |
The above is an example, not an instance. You may prefer to look at its actual use. Download the code written by the author and enjoy it.