adapter pattern

adapter pattern gibi facade ve decorator pattern‘leri var. bunlara nesne yonelimli programlama dilleri icin structural pattern’ler deniyor.

data ismindeki structure’daki datalari kullanan c fonk’lari var. bunlar plotter_turn_on, plotter_turn_off, plotter_has_ink, plotter_circle, plotter_square fonk’lari. bu fonk’lari hic bozmadan cpp kodlari icinde kullanmak istersek plotter ismindeki class icinden cagirabiliyoruz. yani cagirdigimiz fonk’lari artik plotter_turn_on() seklinde degil, plotter.turn_on() seklinde cagirabiliyoruz. class ile cagirdigimiz fonk’larin parametrelerini de structure icindeki datalara atiyoruz.

adapter class’lari ile diger class’lara ya da c++’ta yazilmamis c fonk’larina erisim saglanabilir. asagida c fonk’larina erisim saglama var.

teknik aciklamasi:

adapter class’lar, nesneler arasinda relationship saglayan yapilardir. bir nesneyi baska bir nesneye uyumlu hale getirmeye yarar. hic bir zaman yeni bir sistem olustururken kullanilmazlar. sadece requirement’lar degistiginde ve bizim yeni sistemimiz ile uyumlu olmayan mevcut nesnelere yeni fonksiyonellikler eklenmesi gerektiginde kullaniliyor.
kaynak

#include <iostream>
#include <stdio.h>

using namespace std;

struct data
{
    bool ink_level;
    double center_x;
    double center_y;
    double radius;
    double p1_x;
    double p1_y;
    double p2_x;
    double p2_y;
};

void plotter_turn_on()
{
    printf("plotter has turned on\n");
}

void plotter_turn_off()
{
    printf("plotter has turned off\n");
}

bool plotter_has_ink()
{
    printf("return bool ink_level\n");
    return true;
}

void plotter_circle(struct data a)
{
    printf("circle has drawn\n");
}

void plotter_square(struct data a)
{
    printf("circle has drawn\n");
}

class plotter
{
    public:
    void turn_on()
    {
        plotter_turn_on();
    }

    void turn_off()
    {
        plotter_turn_off();
    }

    bool has_ink()
    {
        return plotter_has_ink();
    }

    void circle(double x, double y, double z)
    {
        data circle_data;

        circle_data.center_x = x;
        circle_data.center_y = y;
        circle_data.radius   = z;

        plotter_circle(circle_data);
    }

    void square(double x, double y, double z, double t)
    {
        data square_data;

        square_data.p1_x = x;
        square_data.p1_y = y;
        square_data.p2_x = z;
        square_data.p2_y = t;

        plotter_circle(square_data);
    }
};

int main()
{
    plotter Plotter;

    Plotter.turn_on();
    Plotter.turn_off();
    Plotter.has_ink();
    Plotter.circle(3,2,4);
    Plotter.square(1,2,4,6);

    return 0;
}

pattern yukaridaki kodlarin farkli source dosyalarina dagitilmis hali, projelendirilmis hali asagida. proje code blocks projesi’dir. buradan indirilebilir.


aslinda yukaridaki kod tam olarak adapter pattern olmayabilir. bunun asil sekli adapter class’inin icinde linklenecek olan c fonk’larina ya da link’lenecek olan cpp class’larina pointer’lar ile linkleme. asagidaki kod da bunu gosteriyor.
kaynak

// Abstract Target
class AbstractPlug {
public:
    void virtual RoundPin(){}
    void virtual PinCount(){}
};
// Concrete Target
class Plug : public AbstractPlug {
public:
    void RoundPin() {
        cout << " I am Round Pin" << endl;
    }
    void PinCount() {
        cout << " I have two pins" << endl;
    }
};
// Abstract Adaptee
class AbstractSwitchBoard {
public:
    void virtual FlatPin() {}
    void virtual PinCount() {}
};
// Concrete Adaptee
class SwitchBoard : public AbstractSwitchBoard {
public:
    void FlatPin() {
                cout << " Flat Pin" << endl;
    }
    void PinCount() {
                cout << " I have three pins" << endl;
    }
};
// Adapter
class Adapter : public AbstractPlug {
public:
    AbstractSwitchBoard *T;
    Adapter(AbstractSwitchBoard *TT) {
                T = TT;
    }
    void RoundPin() {
                T->FlatPin();
    }
    void PinCount() {
                T->PinCount();
    }
};
// Client code
void _tmain(int argc, _TCHAR* argv[])
{
    SwitchBoard *mySwitchBoard = new SwitchBoard; // Adaptee
    // Target = Adapter(Adaptee)
    AbstractPlug *adapter = new Adapter(mySwitchBoard);
    adapter->RoundPin();
    adapter->PinCount();
}