 |
Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of
incompatible interfaces.
Frequency of use: medium high
|
|
 |
The classes and/or objects participating in this pattern are:
- Target (ChemicalCompound)
- defines the domain-specific interface that Client uses.
- Adapter (Compound)
- adapts the interface Adaptee to the Target interface.
- Adaptee (ChemicalDatabank)
- defines an existing interface that needs adapting.
- Client (AdapterApp)
- collaborates with objects conforming to the Target interface.
This structural code demonstrates the Adapter pattern which maps the interface of one class onto
another so that they can work together. These incompatible
classes may come from different libraries or frameworks.
Show code
|
// Adapter pattern -- Structural example
|
|
using System;
namespace DoFactory.GangOfFour.Adapter.Structural
{
// Mainapp test application
class MainApp
{
static void Main()
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();
// Wait for user
Console.Read();
}
}
// "Target"
class Target
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
// "Adapter"
class Adapter : Target
{
private Adaptee adaptee = new Adaptee();
public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}
// "Adaptee"
class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
|
Output
Called SpecificRequest()
|
This real-world code demonstrates the use of a legacy
chemical databank. Chemical compound
objects access the databank through an Adapter interface.
Show code
|
// Adapter pattern -- Real World example
|
|
using System;
namespace DoFactory.GangOfFour.Adapter.RealWorld
{
// MainApp test application
class MainApp
{
static void Main()
{
// Non-adapted chemical compound
Compound stuff = new Compound("Unknown");
stuff.Display();
// Adapted chemical compounds
Compound water = new RichCompound("Water");
water.Display();
Compound benzene = new RichCompound("Benzene");
benzene.Display();
Compound alcohol = new RichCompound("Alcohol");
alcohol.Display();
// Wait for user
Console.Read();
}
}
// "Target"
class Compound
{
protected string name;
protected float boilingPoint;
protected float meltingPoint;
protected double molecularWeight;
protected string molecularFormula;
// Constructor
public Compound(string name)
{
this.name = name;
}
public virtual void Display()
{
Console.WriteLine("\nCompound: {0} ------ ", name);
}
}
// "Adapter"
class RichCompound : Compound
{
private ChemicalDatabank bank;
// Constructor
public RichCompound(string name) : base(name)
{
}
public override void Display()
{
// Adaptee
bank = new ChemicalDatabank();
boilingPoint = bank.GetCriticalPoint(name, "B");
meltingPoint = bank.GetCriticalPoint(name, "M");
molecularWeight = bank.GetMolecularWeight(name);
molecularFormula = bank.GetMolecularStructure(name);
base.Display();
Console.WriteLine(" Formula: {0}", molecularFormula);
Console.WriteLine(" Weight : {0}", molecularWeight);
Console.WriteLine(" Melting Pt: {0}", meltingPoint);
Console.WriteLine(" Boiling Pt: {0}", boilingPoint);
}
}
// "Adaptee"
class ChemicalDatabank
{
// The Databank 'legacy API'
public float GetCriticalPoint(string compound, string point)
{
float temperature = 0.0F;
// Melting Point
if (point == "M")
{
switch (compound.ToLower())
{
case "water" : temperature = 0.0F; break;
case "benzene" : temperature = 5.5F; break;
case "alcohol" : temperature = -114.1F; break;
}
}
// Boiling Point
else
{
switch (compound.ToLower())
{
case "water" : temperature = 100.0F; break;
case "benzene" : temperature = 80.1F; break;
case "alcohol" : temperature = 78.3F; break;
}
}
return temperature;
}
public string GetMolecularStructure(string compound)
{
string structure = "";
switch (compound.ToLower())
{
case "water" : structure = "H20"; break;
case "benzene" : structure = "C6H6"; break;
case "alcohol" : structure = "C2H6O2"; break;
}
return structure;
}
public double GetMolecularWeight(string compound)
{
double weight = 0.0;
switch (compound.ToLower())
{
case "water" : weight = 18.015; break;
case "benzene" : weight = 78.1134; break;
case "alcohol" : weight = 46.0688; break;
}
return weight;
}
}
}
|
Output
Compound: Unknown ------
Compound: Water ------
Formula: H20
Weight : 18.015
Melting Pt: 0
Boiling Pt: 100
Compound: Benzene ------
Formula: C6H6
Weight : 78.1134
Melting Pt: 5.5
Boiling Pt: 80.1
Compound: Alcohol ------
Formula: C2H6O2
Weight : 46.0688
Melting Pt: -114.1
Boiling Pt: 78.3
|
This .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features.
Show code
|
// Adapter pattern -- .NET optimized
|
See our Singleton page for a .NET optimized code sample.
|
|
|