Design Mode 6: adapter pattern (adapter Mode)

Source: Internet
Author: User

From: http://www.cnblogs.com/zhenyulu/articles/39386.html

Reference: http://www.dofactory.com/Patterns/PatternAdapter.aspx

I. Adapter Mode

The adapter mode converts an interface of a class into another interface that the client expects, so that the two classes that the original interface does not match and cannot work together can work together.

Name Origin

This is like a transformer, which converts one voltage to another. The domestic electricity voltage in the United States is 110 V, while that in China is 220 V. If you want to use us appliances in China, you must have a transformer that converts the 220v voltage to the 110v voltage. This transformer is an adapter.

The adapter mode is also similar to the packaging process of the goods: the actual appearance of the packaged goods is covered and changed by the packaging, so someone calls this mode the wrapper mode. In fact, we often write many such Wrapper Classes to package existing classes so that they can have interfaces that meet the needs.

Two adapter Modes

The adapter mode can be a class adapter mode or an Object Adapter mode. We will discuss the two adapter modes respectively.

Ii. Structure of the adapter mode of the class:

 

The figure shows that the adaptee class does not have a request method, and the customer expects this method. To enable the customer to use the adaptee class and provide an intermediate link, that is, the class adapter class, the adapter class implements the Target Interface and inherits from adaptee, the request method of the adapter Class re-encapsulates the specificrequest method of adaptee to achieve adaptation.

Because the adapter and adaptee are inherited, this determines that the adapter mode is a class.

The role involved in this adapter mode includes:

Target role: This is the interface the customer expects. Because C # does not support multi-inheritance, the target must be an interface, not a class.
Source (adaptee) role: the class to be adapted.
Adapter role: converts the source interface to the target interface. This role must be a class.

Iii. Implementation of the adapter mode of the class:

The following program provides a schematic Implementation of the adapter mode of the class:

Using system; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; </P> <p> namespace adapter_pattern <br/> {<br/> // class adapter pattern -- Structural example <br/> using system; </P> <p> // "itarget" <br/> interface itarget <br/> {<br/> // methods <br/> void request (); <br/>}</P> <p> // "adaptee" <br/> class adaptee <br/> {<br/> // methods <br/> Public void specificrequest () <br/> {<br/> console. writeline ("called specificrequest ()"); <br/>}</P> <p> // "adapter" <br/> class adapter: adaptee, itarget <br/>{< br/> // implements itarget interface <br/> Public void request () <br/> {<br/> // possibly do some data manipulation <br/> // and then call specificrequest <br/> This. specificrequest (); <br/>}</P> <p>/**/<br/> /// <summary> <br/> // client Test <br/> // </Summary> <br/> public class client <br/> {<br/> Public static void main (string [] ARGs) <br/>{< br/> // create adapter and place a request <br/> itarget T = new adapter (); <br/> T. request (); <br/>}< br/>

4. Structure of the object's adapter mode:

 

It can be seen that the client needs to call the request method, but adaptee does not have this method. To enable the client to use the adaptee class, a Wrapper class adapter is required. This packaging class encapsulates an adaptee instance to connect the client with adaptee. Since the adapter and adaptee are delegates, this determines that the adapter mode is object.

The role involved in this adapter mode includes:

Target role: This is the interface the customer expects. The target can be a specific or abstract class or interface.
Source (adaptee) role: the class to be adapted.
Adapter role: a adaptee object is encapsulated internally to convert the source interface to the target interface.

V. Implementation of the adapter mode of the object:

The following program provides a schematic Implementation of the adapter mode of the class:

Using system; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; </P> <p> namespace adapter_pattern <br/> {<br/> // adapter pattern -- Structural example </P> <p>/"target" <br/> class target <br/>{< br/> // methods <br/> virtual public void request () <br/>{< br/> // normal implementation goes here <br/>}</P> <p> // "adapter" <br/> class adapter: target <br/> {<br/> // fields <br/> private adaptee = new adaptee (); </P> <p> // methods <br/> override public void request () <br/> {<br/> // possibly do some data manipulation <br/> // and then call specificrequest <br/> adaptee. specificrequest (); <br/>}</P> <p> // "adaptee" <br/> class adaptee <br/>{< br/> // Methods <br/> Public void specificrequest () <br/> {<br/> console. writeline ("called specificrequest ()"); <br/>}</P> <p>/**/<br/> /// <summary> <br/> // client Test <br/> // </Summary> <br/> public class client <br/> {<br/> Public static void main (string [] ARGs) <br/>{< br/> // create adapter and place a request <br/> Target T = new adapter (); <br/> T. request (); <br/> console. read (); <br/>}< br/>

6. Under what circumstances should I use the adapter mode?

Use the adapter mode in the following situations:

1. The system needs to use an existing class, and such an interface does not meet the requirements of the system.
2. Create a reusable class for some classes that are not highly correlated with each other, including some classes that may be introduced in the future. These source classes do not necessarily have very complex interfaces.
3. In the design (for object adapters), you need to change multiple existing subclass interfaces. If you use the class adapter mode, you need to create an adapter for each subclass, this is not practical.

VII. An example of practical application of the adapter Mode

The following program demonstrates the application of class adapter and Object Adapter.

Using system; <br/> using system. collections. generic; <br/> using system. LINQ; <br/> using system. text; </P> <p> namespace adapter_pattern <br/> {<br/> // example of implementing the adapter pattern <br/> using system; </P> <p> // target <br/> Public interface ICAR <br/> {<br/> void drive (); <br/>}</P> <p> // direct use without adapter <br/> public class ctoyota: ICAR <br/>{< br/> Public void drive () <br/>{< br/> console. writeline ("vroom, we're off in our Toyota "); <br/>}</P> <p> // adaptee <br/> public class ccessna <br/>{< br/> Public void fly () <br/> {<br/> console. writeline ("static Runup OK, we're off in our c172 "); <br/>}</P> <p> // class adapter <br/> public class cdrivablecessna: ccessna, ICAR <br/> {<br/> Public void drive () {base. fly () ;}< br/>}</P> <p> // Object Adapter <br/> public class cdrivablecessna2: ICAR <br/>{< br/> private ccessna m_ocontained; </P> <p> Public cdrivablecessna2 () <br/>{< br/> m_ocontained = new ccessna (); <br/>}</P> <p> Public void drive () {m_ocontained.fly ();} <br/>}</P> <p> // client <br/> public class client <br/> {<br/> Public static void main (string [] ARGs) <br/>{< br/> ICAR ocar = new ctoyota (); </P> <p> console. write ("class adapter: driving an automobile"); <br/> ocar. drive (); <br/> ocar = new cdrivablecessna (); <br/> console. write ("driving a Cessna"); <br/> ocar. drive (); <br/> ocar = new cdrivablecessna2 (); <br/> console. write ("Object Adapter: driving a Cessna"); <br/> ocar. drive (); <br/>}< br/>
8. About the adapter Mode

Note the following when implementing the adapter mode:

1. The target interface can be omitted and the mode degrades. However, this method seems Mediocre but not mediocre. It can make adaptee unnecessary (refer to the default adapter mode ). The expression is that the parent class implements the default method, and the Child class only needs to implement its own unique method. This is similar to the template mode.
2. the adapter class can be an abstract class.
3. the adapter mode with parameters. In this way, the adapter class can return a suitable instance to the client according to the parameters.

 

Other examples

// Adapter pattern -- real world example <br/> using system; <br/> namespace dofactory. gangoffour. adapter. realworld <br/>{</P> <p> // <summary> </P> <p> // mainapp startup class for real-world </P> <p> // adapter design pattern. </P> <p> // </Summary> </P> <p> class mainapp <br/>{</P> <p> // <Summary> </P> <p> // entry point into console application. </P> <p> // </Summary> </P> <p> static void main () <br/>{</P> <p> // non-adapted chemical compound </P> <p> Compound unknown = new compound ("unknown "); </P> <p> unknown. display (); </P> <p> // adapted chemical compounds </P> <p> compound water = new richcompound ("water "); </P> <p> water. display (); </P> <p> Compound benzene = new richcompound ("Benzene"); </P> <p> benzene. display (); </P> <p> Compound ethanol = new richcompound ("ETHANOL"); </P> <p> Ethanol. display (); </P> <p> // wait for user </P> <p> console. readkey (); </P> <p >}</P> <p> // <summary> </P> <p> // 'target' class </P> <p> // </Summary> </P> <p> class compound <br/>{</P> <p> protected string _ chemical; </P> <p> protected float _ boilingpoint; </P> <p> protected float _ meltingpoint; </P> <p> protected double _ molecularweight; </P> <p> protected string _ molecularformula; </P> <p> // constructor </P> <p> Public compound (string chemical) <br/>{</P> <p> This. _ chemical = chemical; </P> <p >}</P> <p> Public Virtual void display () <br/>{</P> <p> console. writeline ("/ncompound: {0} ------", _ chemical ); </P> <p >}</P> <p> // <summary> </P> <p> // 'adapter 'class </P> <p> // </Summary> </P> <p> class richcompound: compound <br/>{</P> <p> private chemicaldatabank _ bank; </P> <p> // constructor </P> <p> Public richcompound (string name) </P> <p>: Base (name) <br/>{</P> <p >}</P> <p> Public override void display () <br/>{</P> <p> // The adaptee </P> <p> _ bank = new chemicaldatabank (); </P> <p> _ boilingpoint = _ bank. getcriticalpoint (_ chemical, "B"); </P> <p> _ meltingpoint = _ bank. getcriticalpoint (_ chemical, "M"); </P> <p> _ molecularweight = _ bank. getmolecularweight (_ chemical); </P> <p> _ molecularformula = _ bank. getmolecularstructure (_ chemical); </P> <p> base. display (); </P> <p> console. writeline ("formula: {0}", _ molecularformula); </P> <p> console. writeline ("Weight: {0}", _ molecularweight); </P> <p> console. writeline ("melting PT: {0}", _ meltingpoint); </P> <p> console. writeline ("Boiling PT: {0}", _ boilingpoint ); </P> <p >}</P> <p> // <summary> </P> <p> // 'adaptee 'class </P> <p> // </Summary> </P> <p> class chemicaldatabank <br/>{</P> <p>/ /The databank 'legacy API '</P> <p> public float getcriticalpoint (string compound, string point) <br/>{</P> <p> // melting point </P> <p> If (point = "M ") <br/>{</P> <p> switch (compound. tolower () <br/>{</P> <p> case "water": Return 0.0f; </P> <p> case "Benzene": Return 5.5f; </P> <p> case "ETHANOL": Return-114.1f; </P> <p> default: Return 0f; </P> <p >}</P> <p> // boiling point </P> <p> else <br/> {</P> <p> switch (compound. tolower () <br/>{</P> <p> case "water": Return 100366f; </P> <p> case "Benzene": Return 80.1f; </P> <p> case "ETHANOL": Return 78.3f; </P> <p> default: Return 0f; </P> <p >}</P> <p> Public String getmolecularstructure (string compound) <br/>{</P> <p> switch (compound. tolower () <br/>{</P> <p> case "water": Return "H20"; </P> <p> case "Benzene ": return "c6h6"; </P> <p> case "ETHANOL": Return "C2H5OH"; </P> <p> default: Return ""; </P> <p >}</P> <p> Public double getmolecularweight (string compound) <br/>{</P> <p> switch (compound. tolower () <br/>{</P> <p> case "water": Return 18.015; </P> <p> case "Benzene": Return 78.1134; </P> <p> case "ETHANOL": Return 46.0688; </P> <p> default: Return 0d; </P> <p >}</P> <p>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.