Strukturelle Entwurfsmuster

Strukturelle Entwurfsmuster

Strukturelle Entwurfsmuster sind Muster, die beschreiben, wie Objekte und Klassen kombiniert werden können und eine große Struktur bilden, und die das Design erleichtern, indem sie einen einfachen Weg identifizieren, um Beziehungen zwischen Entitäten zu realisieren. Es werden sieben strukturelle Muster beschrieben. Diese sind wie folgt:Adapter, Bridge, Composite, Decorator, Facade, Flyweight und Proxy

# Adapterdesignmuster

[**„Adapter“**](https://en.wikipedia.org/wiki/Adapter_pattern) ist, wie der Name schon sagt, das Objekt, das zwei nicht kompatible Schnittstellen miteinander kommunizieren lässt.

**Zum Beispiel:** Wenn Sie ein Iphone 8 (oder ein anderes Apple-Produkt) kaufen, benötigen Sie viele Adapter. Weil die Standardschnittstelle Audiojac oder USB nicht unterstützt. Mit diesen Adaptern können Sie Kopfhörer mit Kabeln oder ein normales Ethernet-Kabel verwenden. Also **"zwei miteinander inkompatible Schnittstellen kommunizieren miteinander"**.

**In technischer Hinsicht bedeutet dies also:** Konvertieren Sie die Schnittstelle einer Klasse in eine andere Schnittstelle, die ein Client erwartet. Adapter lassen Klassen zusammenarbeiten, die sonst aufgrund inkompatibler Schnittstellen nicht möglich wären. Die an diesem Muster beteiligten Klassen und Objekte sind:

Das Adaptermuster gibt 4 Elemente aus

    - **ITarget:** Dies ist die Schnittstelle, die vom Client verwendet wird, um Funktionalität zu erreichen.- **Adaptee:** Dies ist die Funktionalität, die der Client wünscht, aber seine Schnittstelle ist nicht mit dem Client kompatibel.- **Client:** Dies ist die Klasse, die einige Funktionen erreichen möchte, indem sie den Code des Adaptees verwendet.- **Adapter:** Dies ist die Klasse, die ITarget implementieren und den Adaptee-Code aufrufen würde, den der Client aufrufen möchte.

UML

Erstes Codebeispiel (Theoretisches Beispiel) .

public interface ITarget
{
    void MethodA();
}

public class Adaptee
{
    public void MethodB()
    {
        Console.WriteLine("MethodB() is called");
    }
}

public class Client
{
    private ITarget target;

    public Client(ITarget target)
    {
        this.target = target;
    }

    public void MakeRequest()
    {
        target.MethodA();
    }
}  

public class Adapter : Adaptee, ITarget
{
    public void MethodA()
    {
        MethodB();
    }
}

Zweites Codebeispiel (Implementierung in der realen Welt)

/// <summary>
///  Interface: This is the interface which is used by the client to achieve functionality.
/// </summary>
public interface ITarget
{
    List<string> GetEmployeeList();
}

/// <summary>
/// Adaptee: This is the functionality which the client desires but its interface is not compatible with the client.
/// </summary>
public class CompanyEmplyees
{
    public string[][] GetEmployees()
    {
        string[][] employees = new string[4][];

        employees[0] = new string[] { "100", "Deepak", "Team Leader" };
        employees[1] = new string[] { "101", "Rohit", "Developer" };
        employees[2] = new string[] { "102", "Gautam", "Developer" };
        employees[3] = new string[] { "103", "Dev", "Tester" };

        return employees;
    }
}

/// <summary>
/// Client: This is the class which wants to achieve some functionality by using the adaptee’s code (list of employees).
/// </summary>
public class ThirdPartyBillingSystem
{
    /* 
     * This class is from a thirt party and you do'n have any control over it. 
     * But it requires a Emplyee list to do its work
     */

    private ITarget employeeSource;

    public ThirdPartyBillingSystem(ITarget employeeSource)
    {
        this.employeeSource = employeeSource;
    }

    public void ShowEmployeeList()
    {
        // call the clietn list in the interface
        List<string> employee = employeeSource.GetEmployeeList();

        Console.WriteLine("######### Employee List ##########");
        foreach (var item in employee)
        {
            Console.Write(item);
        }

    }
}

/// <summary>
/// Adapter: This is the class which would implement ITarget and would call the Adaptee code which the client wants to call.
/// </summary>
public class EmployeeAdapter : CompanyEmplyees, ITarget
{
    public List<string> GetEmployeeList()
    {
        List<string> employeeList = new List<string>();
        string[][] employees = GetEmployees();
        foreach (string[] employee in employees)
        {
            employeeList.Add(employee[0]);
            employeeList.Add(",");
            employeeList.Add(employee[1]);
            employeeList.Add(",");
            employeeList.Add(employee[2]);
            employeeList.Add("\n");
        }

        return employeeList;
    }
}

/// 
/// Demo
/// 
class Programs
{
    static void Main(string[] args)
    {
        ITarget Itarget = new EmployeeAdapter();
        ThirdPartyBillingSystem client = new ThirdPartyBillingSystem(Itarget);
        client.ShowEmployeeList();
        Console.ReadKey();
    }
}

Wann zu verwenden

  • Einem System erlauben, Klassen eines anderen Systems zu verwenden, das damit nicht kompatibel ist.
  • Ermöglichen Sie die Kommunikation zwischen neuen und bereits bestehenden Systemen, die voneinander unabhängig sind
  • Ado.Net SqlAdapter, OracleAdapter, MySqlAdapter sind die besten Beispiele für Adaptermuster.