14 Nisan 2013 Pazar

GÖZLEMCİ TASARIM MODELİ(OBSERVER DESIGN PATTERN)

Observer pattern,değişiklik yaşanan durum hakkında gerekli birimleri bilgilendirmek için kullanılan bir patern yapısıdır.Observer pattern yapısının genel uml diagramı yandaki gibidir.Peki ne anlatıyor bize bu uml diagram?
Öncelikle elimizde gözlenen(subject) ve gözlemci(observer) sınıfımız olmak zorundadır.Gözlemci sınıfımız altında bulunan update() fonksiyonuyla subject yani gözlenen sınıfında meydana gelen değişikliklerden haberdar edilir.Subject sınıfımızda da addObserver() ve deleteObserver() fonksiyonlarıyla değişen durumlardan haberdar olacak gözemciyi ekleme ve silme işlemleri yapılır.notifyObserver() fonksiyonu ise Observer sınıfının update() fonksiyonunu çağırarak değişikliklerden haberdar etmiş olur.
Observer Pattern yapısı,fonksiyonları bu şekildedir.Fonksiyonların işleyişini örnek bir uygulama üzerinden anlatalım...

Yandaki resimde görüldüğü gibi uygulamamız restaurantta verilen siparişlerin işleyişleri hakkında olacaktır.Mutfakta çalışan aşçımız,kasada bulunan kasiyer ve siparişi alan garson bulunmaktadır.Aşçı yapacağı yemekleri bilmek,kasiyerde yemeklerden alınması gereken parayı bilmek ister.O zaman garson sipariş alınca hem aşçıyı hem de kasiyeri bilgilendirsin.Elimizde bu durum da iki gözlemci; mutfak(Kitchen) ,kasiyer(Chaier) ve bir de gözlenen/öznemiz garson (Waiter) vardır.




Uml aşağıdaki gibi olacaktır...

















İşte kodumuz.....


#include<iostream>
#include<vector>
#include<string>
#include<list>

using namespace std;

//***********
//Observer
//***********
class Observer
{
public:
virtual void updata(string s,int i,double d)=0;
};

/***********
//Chaier
//***********
class Chaier:public Observer,Display
{
Waiter *w;
vector<string> name;
vector<int >number;
vector<double >cost;
public:
Chaier(Waiter *w)
{
this->w=w;
w->registerObserver(this);
}
~Chaier()
{
w->removeObserver(this);
}
void updata(string new_name,int new_number,double new_cost)
{
name.push_back(new_name);
number.push_back(new_number);
cost.push_back(new_cost);
display();
}
void display()
{
double total_cost=0;
cout<<endl<<"***************** CHAIER DISPLAY ***************"<<"\n\n";
cout<<"Name       Number     Cost"<<endl<<"--------------------------"<<"\n";
for(int i=0;i<name.size();i++)
{
cout<<name[i]<<"         "<<number[i]<<"        "<<number[i]*cost[i]<<"\n";
total_cost+=number[i]*cost[i];
}
cout<<endl<<"TOTAL COST : "<<total_cost<<"\n";
}
};

//***********
//Kitchen
//***********
class Kitchen:public Observer,Display
{
Waiter *w;
vector<string> name;
vector<int >number;
vector<double >cost;
public:
Kitchen(Waiter *w)
{
this->w=w;
w->registerObserver(this);
}
~Kitchen()
{
w->removeObserver(this);
}
void display()
{

cout<<endl<<"************ KITCHEN DISPLAY **************"<<"\n\n";
cout<<"Name       Number"<<endl<<"---------------------"<<"\n\n";
for(int i=0;i<name.size();i++)
{
cout<<name[i]<<"        "<<number[i]<<"      "<<"\n";
}
}
void updata(string new_name,int new_number,double new_cost)
{
name.push_back(new_name);
number.push_back(new_number);
cost.push_back(new_cost);
display();
}

};

//***********
//Display
//***********
class Display
{
public:
virtual void display()=0;
};

//***********
//Subject
//***********
class Subject
{
protected:
string name;
int number;
double cost;
list<Observer*> observer; //Tüm izliyicelerin tutulduğu liste
public:
virtual void registerObserver(Observer *o)=0;
virtual void removeObserver(Observer *o)=0;
virtual void notifyObserver()=0;

};

//***********
//Waiter
//***********
class Waiter:public Subject
{
public:
void registerObserver(Observer *o)
{
observer.push_back(o);
}
void removeObserver(Observer *o)
{
observer.remove(o);
}
void notifyObserver() //Tüm izlyicilerin bilgilerini yeniler.
{
for(list<Observer*>::iterator it=observer.begin();it!=observer.end();it++)
(*it)->updata(name,number,cost);
}
void setOrder(string name,int number,double cost)
{
this->name=name;
this->number=number;
this->cost=cost;
         notifyObserver();
}

};

//***********
//Main
//***********
int main()
{
Waiter *waiter=new Waiter();

Kitchen *kitchen=new Kitchen(waiter); //Kitchen gözlemci olarak eklenniyor.
Chaier *chaier=new Chaier(waiter);    // Chaier gözlemci olarak ekleniyor.

waiter->setOrder("Waffle",2,10);
waiter->setOrder("Kumpir",3,7.5);

delete kitchen; //Kitchen gözlemcilerden çıkarılıyor.Artık değişikliklerden haberda edilmeyecek.

waiter->setOrder("Sutlac",1,7.50);
system("pause");
return 0;
}
Buda output...










2 yorum:

  1. Noktalama işaretlerine ve paragraf kullanımına lütfen dikkat edin. Anlamak hakkaten çok güç.

    YanıtlaSil