Wzorce projektowe (10)

Autor: Damian Chodorek • Opublikowany: 23 lipca 2015 • Kategoria: kursy, wzorce projektowe

Adapter.

Adapter to zarówno wzorzec obiektowy jak i klasowy. Jego celem jest umożliwienie współpracy dwóm klasom o niekompatybilnych interfejsach, przekształcenie interfejsu jednej z klas na taki, który będzie mógł być wykorzystany przez inną klasę. Istnieją dwa warianty tego wzorca:

  • klasowy – klasa adaptera klasowego dziedziczy prywatnie po klasie adaptowanej i publicznie po klasie klienta implementując jego metody,
  • obiektowy – klasa adaptera dziedziczy po klasie klienta oraz zawiera w sobie obiekt klasy adaptowanej.

Klasy

class Adaptee{/*
klasa adaptowana - jej interfejs jest niezgodny z interfejsem klienta
*/};

class Client{/*
klasa klienta - jej metody różnią się nazwami od metod klasy Adaptee, ale odpowiadają im (robią to samo)
*/};

class Adapter{/*
jest to "przejściówka" z interfejsu Adaptee  do Client
*/};

Etapy działania

  • Klienta korzysta z interfejsu adaptera.

Konsekwencje

  • W przypadku adaptera klasowego istnieje możliwość przeładowania metod klasy adaptowanej. W przypadku adaptera obiektowego nie ma takiej możliwości.
  • Można rozszerzać funkcjonalność adaptowanej klasy.
  • Im większa jest niekompatybilność, tym większy jest narzut wydajnościowy.

Przykłady

Adapter klasowy:

#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

///klasa klienta
class Printer
{
public:
    virtual void printToStd(string str)=0;
    virtual void printToFile(string str)=0;
};

///klasa adaptowana
class Poet
{
public:
    void sayToStd(string str) { cout<<str<<endl; }
    void writeToPaper(string str)
    {
        ofstream file("paperFile.txt");
        file<<str;
    }
};

///adapter - opakowuje klasę Poet w interfejs klasy Printer
class Poet_Printer_Adapter: private Poet, public Printer
{
public:
    void printToStd(string str) { sayToStd(str); }
    void printToFile(string str) { writeToPaper(str); }
};

int main(int argc, const char *argv[])
{
    Poet_Printer_Adapter adapter;
    Printer* myPrinter=&adapter;
    myPrinter->printToStd("Printer using Poet...");

    return 0;
}

Adapter obiektowy:

#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

///klasa klienta
class Printer
{
public:
    virtual void printToStd(string str)=0;
    virtual void printToFile(string str)=0;
};

///klasa adaptowana
class Poet
{
  public:
    void sayToStd(string str) { cout<<str<<endl; }
    void writeToPaper(string str)
    {
      ofstream file("paperFile.txt");
      file<<str;
    }
};

///adapter - opakowuje klasę Poet w interfejs klasy Printer
class Poet_Printer_Adapter: public Printer
{
public:
    void printToStd(string str) { _poet.sayToStd(str); }
    void printToFile(string str) { _poet.writeToPaper(str); }
private:
    Poet _poet;

};

int main(int argc, const char *argv[])
{
    Poet_Printer_Adapter adapter;
    Printer* myPrinter=&adapter;
    myPrinter->printToStd("Printer using Poet");

    return 0;
}

część 11

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.