Mencoba Observer Pattern dan Strategy Pattern di C++

Saya tidak mempelajari ilmu komputer sebagai background pendidikan saya, dan ketika saya “nemu” design pattern dalam pengembangan software, hal itu menurut saya adalah keberuntungan :). Kenapa? walaupun waktu kuliah isinya juga coding, ( kebanyakan untuk hardware seperti : microcontroller, PLC, microprocessor, atau program-program kecil untuk interfacing), namun tidak menggunakan teknik pengembangan software apapun. Cuma prosedural dan efisiensi penggunaan memori – dan itu memang sudah cukup - . Hal itu sangat berbeda jika kita ingin mengembangkan software yang komplek dan besar. Sebuah teknik/pola harus ada, dan jawabannya adalah design pattern.

_ Design Pattern _bisa diartikan cara/pola/pattern pemrograman yang dipakai saat menghadapi masalah-masalah tertentu. Masalah tertentu dengan pattern tertentu. “Pattern” disini bisa jadi sudah ada atau belum ada. Pattern yang sudah ada sudah banyak dan digunakan untuk masalah yang sering muncul dalam pemrograman. Lihat wiki design pattern untuk daftar pattern – pattern tersebut.

Kali ini saya ingin mencoba observer dan strategy pattern menggunakan C++. Tidak seperti di Java, C++ tidak ada dukungan untuk implementasi observer pattern (lihat blog post saya ttg implementasi observer di Java). Namun, untungnya di C++ ada pointer :). Observer Pattern dipakai saat masalah seperti ini muncul:

“_terdapat sebuah object/beberapa object yang perlu diketahui keadaan/state-nya oleh sebuah object/beberapa object lain_”

Contoh riil-nya sebagai berikut :

“Sebuah program mendapat data objek bergerak dari komputer lain melalui jaringan dan objek tersebut akan ditampilkan di tampilan peta 2D dan tampilan 3D. Setiap perubahan data objek akan di update di tampilan 2D dan 3D”

[caption id=“attachment_263” align=“aligncenter” width=“300” caption=“offgnd_observer_uml”] [/caption]

Subject adalah object yang di-observe (diamati) dan memiliki daftar observer yang terdaftar, bisa menambah dan mengurangi observer-nya. Sedangkan observer adalah object yang meng-observe (pengamat). Concrete subject adalah object turunan dari subject, dan memiliki object yang bisa di observe. Concrete Observer adalah object turunan Observer untuk me-re-implementasi fungsi update dari observer. Setelah semunya tampak jelas, waktunya kita coding :

[sourcecode language=“cpp”] #include #include

class subject;

class observer{ public: observer(){}; ~observer(){}; virtual void update(subject* updated_subject)=0; };

class subject{ public: subject(); ~subject(){}; virtual void add(observer* ob); virtual void remove(observer* ob); virtual void notify(); private: std::list list_observer; }; [/sourcecode]


Source : Observer.cpp

[sourcecode language=“cpp”] #include “observer.h”

subject::subject() { // }

void subject::add(observer *ob) { list_observer.push_back(ob); }

void subject::remove(observer *ob) { list_observer.remove(ob); }

void subject::notify() { std::list::iterator i;

for(i=list_observer.begin();i!=list_observer.end();i++) { (*i)->update(this); } } [/sourcecode]

mari kita pakai disini : main.cpp

[sourcecode language=“cpp”]

#include #include “observer.h” #include

using namespace std;

/* Kelas objek bergerak , memiliki koordinat x,y,z yg menunjukkan data posisi */ class SimObject { public: SimObject(float fx,float fy,float fz) { SetTranslation(fx,fy,fz); }; ~SimObject(){}; void SetTranslation(float fx,float fy,float fz) { x=fx; y=fy; z=fz; }; void GetTranslation(float& fx,float& fy,float& fz) { fx=x; fy=y; fz=z; }; private: float x,y,z; };

/* Updater: concrete subject * memiliki daftar objek bergerak (instan SimObject) / class Updater:public subject { public: Updater(){    mStateUpdate=UPD_OBJ; }; ~Updater(){}; void AddObject(SimObject newobj) { mObjects.push_back(newobj); mStateUpdate=NEW_OBJ; notify(); mStateUpdate=UPD_OBJ; } void DelObject(SimObject* delobj) { mObjects.remove(delobj); mStateUpdate=DEL_OBJ; notify(); mStateUpdate=UPD_OBJ; } void GetListObject(list& listobj) { listobj=mObjects; }; short int GetStateUpdate() { return mStateUpdate; }; private: enum{ NEW_OBJ,DEL_OBJ,UPD_OBJ } mStateUpdate; listmObjects; }; //strategy pattern: implementasi algoritma dipisah //MoveAlgorithm: abstract class untuk algorithm, digunakan spt halnya interface di Java/Delphi class MoveAlgorithm { public: MoveAlgorithm(){}; ~MoveAlgorithm(){}; virtual void DoMove(float x,float y,float z)=0; }; //turunan MoveAlgorithm class MoveAlgorithm2D:public MoveAlgorithm { public: MoveAlgorithm2D(){}; ~MoveAlgorithm2D(){}; virtual void DoMove(float x,float y,float z) { cout<<“Move2D x: “<add(this); mMoveAlgo=NULL; }; ~Viewer() { mSubject->remove(this); }; void SetMoveAlgorithm(MoveAlgorithm* ma) { mMoveAlgo=ma; }; void update(subject *updated_subject) { if(updated_subject==mSubject) { short int s= mSubject->GetStateUpdate(); if(s==0){ cout<<“new object added”<<endl; } else if(s==1){ cout<<“object deleted”<<endl; } else if(s==2){ Move(); } }; };

void Move() { list listobject; mSubject->GetListObject(listobject); for(list::iterator it=listobject.begin();it!=listobject.end();it++) { float x,y,z; (it)->GetTranslation(x,y,z); if(mMoveAlgo!=NULL) { mMoveAlgo->DoMove(x,y,z); }else cout<<“Exception: Move Algorithm is NULL”<<endl; }; }; private: Updater mSubject; MoveAlgorithm* mMoveAlgo; };

//Main

int main() { cout<SetMoveAlgorithm(new MoveAlgorithm2D());

Viewer* viewer2=new Viewer(updater); viewer2->SetMoveAlgorithm(new MoveAlgorithm3D());

SimObject* object1=new SimObject(10.0,5.0,2.0); SimObject* object2=new SimObject(2.0,6.5,2.0); SimObject* object3=new SimObject(11.0,2.0,2.0);

updater->AddObject(object1); updater->AddObject(object2); updater->AddObject(object3);

updater->notify();

updater->DelObject(object1);

updater->notify(); system(“pause”); }

[/sourcecode]

//re-edit again later :)

comments powered by Disqus