Adapter and Facade Design Pattern in C#

Adapter and Facade design pattern:

As per the WikiPedia "An Adapter is used when the wrapper must respect a specific interface and must support a polymorphic behavior. On the other hand, a facade is used when one wants an easier or simpler interface to work with."

Let's move ahead from the WikiPedia and get the sense in more simple terms.

The Adapter pattern just links two incompatible interfaces whereas Facade simplifies the implementations. If we put the analogy in our day-to-day life then:

Adapter = Making a square peg fit into a round hole.

Facade = A single Control Panel to run all the internal components.

Let's have a very simple and well-articulated example to understand the difference.

Imagine you've got some domain classes and from the UI you want to interact with them. A facade can be used to provide functions that can be called from the UI layer so that the UI layer doesn't know about any domain classes other than the facade. That means that instead of calling the functions in the domain classes you call a single function from the facade then that will be responsible of calling the necessary functions from the other classes.

An adapter, on the other hand, can be used to integrate other external components that might have the same functionality you need but their functions are not called quite the same way. Say you've got a Car class in your domain and you work with an external car provider that has a Car class defined as well. In this class, you've got the function car.getDoors() but the external provider has the equivalentcar.getNumDoors(). You don't want to change the way you call this function, so you can use an adapter class to wrap the external Car class so that a call to getDoors() of the adapter is delegated togetNumDoors() of the external class.

Again I would like to quote a diagram from the WikiPedia (followed by an example) to provide a feel for how Facade simplifies things.

Facade

This is an abstract example of how a client interacts with a facade (the "computer") to a complex system (internal computer parts, like CPU and Hard Drive and so on).

class Pattern_Facade

{

    public static void Main(String[] args)

    {

        ComputerFacade computer = new ComputerFacade();

        computer.start();

    }

}

 

/* Complex parts */

class CPU

{

    public void Freeze() { }

    public void Jump(long position) { }

    public void Execute() { }

}

 

class Memory

{

    public void Load(long position, byte[] data) { }

}

 

class HardDrive

{

    public byte[] Read(long lba, int size) { return new Byte[5]; }

}

 

/* Facade */

class ComputerFacade

{

    private CPU processor;

    private Memory ram;

    private HardDrive hd;

    private const long BOOT_ADDRESS = 00000;

    private const long BOOT_SECTOR = 00000;

    private const int SECTOR_SIZE = 0;

 

    public ComputerFacade()

    {

        this.processor = new CPU();

        this.ram = new Memory();

        this.hd = new HardDrive();

    }

    public void start()

    {

        processor.Freeze();

        ram.Load(BOOT_ADDRESS, hd.Read(BOOT_SECTOR, SECTOR_SIZE));

        processor.Jump(BOOT_ADDRESS);

        processor.Execute();

    }

} 

On the other hand, an Adaptor pattern is used when you want two different classes with incompatible interfaces to work together (Interfaces may be incompatible but the inner functionality should suit the needs). It allows incompatible classes to work together by converting the interface of one class into an interface expected by the clients.

abstract

The object adapter pattern is expressed in UML. The adaptor hides the adaptee's interface from the client.

The class adapter pattern is expressed in UML.

/// <summary>

/// In this example, we create a collection of IEmployee objects. Since Employee inherits from IEmployee it can naturally be added

/// to the list. However, the Consultant class is unrelated to IEmployee. In order to allow this class to be added to the same list,

/// we create an adapter class, EmployeeAdapter, which wraps the Consultant class in the IEmployee interface, allowing it to be added

/// to the same list.

/// </summary>

 

class Pattern_Adaptor

{

    static void Main0(string[] args)

    {

        List<IEmployee> list = new List<IEmployee>();

        list.Add(new Employee("Tom"));

        list.Add(new Employee("Jerry"));

        //list.Add(new Consultant("Bruno"));  //cannot convert from 'NET.Consultant' to 'NET.IEmployee'

 

        list.Add(new ConsultantToEmployeeAdapter("Bruno"));  //consultant from existing class

        ShowHappiness(list);

    }

 

    //*** Code below from the existing library does not need to be changed ***

    static void ShowHappiness(List<IEmployee> list)

    {

        foreach (IEmployee i in list)

            i.ShowHappiness();

    }

}

//from the existing library, does not need to be changed

public interface IEmployee

{

    void ShowHappiness();

}

 

public class Employee : IEmployee

{

    private string name;

 

    public Employee(string name)

    {

        this.name = name;

    }

 

    void IEmployee.ShowHappiness()

    {

        Console.WriteLine("Employee " + this.name + " is happy");

    }

}

 

//existing class does not need to be changed

public class Consultant

{

    private string name;

 

    public Consultant(string name)

    {

        this.name = name;

    }

 

    protected void ShowSmile()

    {

        Console.WriteLine("Consultant " + this.name + " smiles");

    }

}

 

public class ConsultantToEmployeeAdapter : Consultant, IEmployee

{

    public ConsultantToEmployeeAdapter(string name)

        : base(name)

    {

    }

 

    void IEmployee.ShowHappiness()

    {

        base.ShowSmile();  //call the parent Consultant class

    }

} 

References: Wikipedia and StackOverflow. 

Up Next
    Ebook Download
    View all
    Learn
    View all