The Adapter design pattern converts the interface of a class into another interface clients expect. This design pattern lets classes work together that couldn‘t otherwise because of incompatible interfaces.
A visualization of the classes and objects participating in this pattern.
The classes and objects participating in this pattern include:
ChemicalCompound
)
Compound
)
ChemicalDatabank
)
AdapterApp
)
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.
using System;
namespace Adapter.Structural
{
/// <summary>
/// Adapter Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Create adapter and place a request
Target target = new Adapter();
target.Request();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Target' class
/// </summary>
public class Target
{
public virtual void Request()
{
Console.WriteLine("Called Target Request()");
}
}
/// <summary>
/// The 'Adapter' class
/// </summary>
public class Adapter : Target
{
private Adaptee adaptee = new Adaptee();
public override void Request()
{
// Possibly do some other work
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}
/// <summary>
/// The 'Adaptee' class
/// </summary>
public class Adaptee
{
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()");
}
}
}
This real-world code demonstrates the use of a legacy chemical databank. Chemical compound objects access the databank through an Adapter interface.
using System;
namespace Adapter.RealWorld
{
/// <summary>
/// Adapter Design Pattern
/// </summary>
public class Program
{
public static void Main(string[] args)
{
// Non-adapted chemical compound
Compound unknown = new Compound();
unknown.Display();
// Adapted chemical compounds
Compound water = new RichCompound("Water");
water.Display();
Compound benzene = new RichCompound("Benzene");
benzene.Display();
Compound ethanol = new RichCompound("Ethanol");
ethanol.Display();
// Wait for user
Console.ReadKey();
}
}
/// <summary>
/// The 'Target' class
/// </summary>
public class Compound
{
protected float boilingPoint;
protected float meltingPoint;
protected double molecularWeight;
protected string molecularFormula;
public virtual void Display()
{
Console.WriteLine("\nCompound: Unknown ------ ");
}
}
/// <summary>
/// The 'Adapter' class
/// </summary>
public class RichCompound : Compound
{
private string chemical;
private ChemicalDatabank bank;
// Constructor
public RichCompound(string chemical)
{
this.chemical = chemical;
}
public override void Display()
{
// The Adaptee
bank = new ChemicalDatabank();
boilingPoint = bank.GetCriticalPoint(chemical, "B");
meltingPoint = bank.GetCriticalPoint(chemical, "M");
molecularWeight = bank.GetMolecularWeight(chemical);
molecularFormula = bank.GetMolecularStructure(chemical);
Console.WriteLine("\nCompound: {0} ------ ", chemical);
Console.WriteLine(" Formula: {0}", molecularFormula);
Console.WriteLine(" Weight : {0}", molecularWeight);
Console.WriteLine(" Melting Pt: {0}", meltingPoint);
Console.WriteLine(" Boiling Pt: {0}", boilingPoint);
}
}
/// <summary>
/// The 'Adaptee' class
/// </summary>
public class ChemicalDatabank
{
// The databank 'legacy API'
public float GetCriticalPoint(string compound, string point)
{
// Melting Point
if (point == "M")
{
switch (compound.ToLower())
{
case "water": return 0.0f;
case "benzene": return 5.5f;
case "ethanol": return -114.1f;
default: return 0f;
}
}
// Boiling Point
else
{
switch (compound.ToLower())
{
case "water": return 100.0f;
case "benzene": return 80.1f;
case "ethanol": return 78.3f;
default: return 0f;
}
}
}
public string GetMolecularStructure(string compound)
{
switch (compound.ToLower())
{
case "water": return "H20";
case "benzene": return "C6H6";
case "ethanol": return "C2H5OH";
default: return "";
}
}
public double GetMolecularWeight(string compound)
{
switch (compound.ToLower())
{
case "water": return 18.015;
case "benzene": return 78.1134;
case "ethanol": return 46.0688;
default: return 0d;
}
}
}
}
The .NET optimized code demonstrates the
same real-world situation as above but uses modern, built-in .NET features,
such as, generics, reflection, LINQ, lambda functions, etc.
You can find an example on our Singleton pattern page.
All other patterns (and much more) are available in our Dofactory .NET product.
Not only does Dofactory .NET cover the Gang of Four and Enterprise patterns, it also includes
pattern architectures, low-code, and RAD (Rapid Application Development) techniques.
Accelerate development to where you can write
entire solutions in just 33 days!.
This unique package will change your developer lifestyle.
Here's what is included: