| |
// Subject / Observer
// Very usefull class
// File: Observer.h
// Date: 5/16/2001
#ifndef _OBSERVER_H
#define _OBSERVER_H
const int MAX_SUBJECTS = 10;
class Subject;
class Observer
{
private:
Subject * subjList[10];
public:
//virtual ~Observer();
virtual void update(int eventID, Subject * pChangedSubject) = 0;
virtual bool attach(Subject * pSubject)
{
static int _nSubjects = 0;
if (_nSubjects < MAX_SUBJECTS)
{
subjList[_nSubjects++] = pObs;
return true;
}
else
return false;
}
};
#endif
// File: Subject.h
// Date: 5/16/2001
#ifndef _SUBJECT_H
#define _SUBJECT_H
#include "Observer.h"
class Subject
{
public:
virtual void notify(int eventID);
virtual bool attach(Observer * pObs);
private:
static const int MAX_OBSERVERS;
static int _nObservers;
Observer * obsList[10];
};
#endif
// File: Suibject.cpp
// Date: 5/16/2001
#include "Subject.h"
const int Subject::MAX_OBSERVERS = 10;
int Subject::_nObservers = 0;
bool Subject::attach(Observer * pObs)
{
if (_nObservers < MAX_OBSERVERS)
{
obsList[_nObservers++] = pObs;
return true;
}
else
return false;
}
void Subject::notify(int eventID)
{
for(int i = 0; i < _nObservers; i++)
obsList[i]->update(eventID, this);
}
// Test subject class "button"
// File: Button.h
#ifndef _BUTTON_H
#define _BUTTON_H
#include "Subject.h"
class Button : public Subject
{
public:
int getID() { return _id; }
bool isPressed() {return _isPressed;}
void press() {_isPressed = true; notify(_id);}
Button() {_isPressed = false; _id = 0;}
Button(int id) {_isPressed = false; _id = id;}
private:
bool _isPressed;
int _id;
};
#endif
// File: CoinManager.h
// Date: 5/16/2001
#ifndef _COINMANAGER_H
#define _COINMANAGER_H
#include <iostream.h>
//#include "Observer.h"
#include "Subject.h"
#include "button.h"
class CoinManager : public Observer
{
public:
void display();
virtual void update(int eventID, Subject *pSubject);
private:
int _seenButtonPress;
};
#endif
// File: CoinManager.cpp
// Date: 5/16/2001
// Purpose: Demonstrate Subject-Observer Pattern Code
#include <iostream>
#include "CoinManager.h"
#include "button.h"
int CoinManager::_nSubjects = 0;
void CoinManager::display( )
{
cout << "button "
<< ( _seenButtonPress ? "has " :
"has not ") << "been pressed \n";
}
CoinManager::CoinManager()
{
_seenButtonPress = false;
}
void CoinManager::update(int eventID, Subject *pSubject)
{
for(int i = 0; i < _nSubjects; i++)
{
if(eventID == _pSubject[i]->getID()) // its a message for me
{
_seenButtonPress = true;
display();
_seenButtonPress = false;
}
}
}
bool CoinManager::attach(Subject * pSubj)
{
if( _nSubjects < MAX_SUBJECTS )
{
_pSubject[_nSubjects] = pSubj;
_pSubject[_nSubjects]->attach(this);
_nSubjects++;
return true;
}
else
return false;
}
// File: Driver.cpp
// Desc: the test program for testing the Object/Observer class
// Date: 5/16/2001
#include "button.h"
#include <iostream.h>
#include <stdlib.h>
#include "coinManager.h"
int main()
{
char keyPress = ' ';
Button coinReleaseBtn(3);
Button dispenseBtn(5);
Button * pSubject = &coinReleaseBtn; // a pointer to the newly created subject
CoinManager coinManager(); // a new manager class
coinReleaseBtn.press();
coinReleaseBtn.press();
coinReleaseBtn.press();
// two ways to attach
coinManager.attach(&dispenseBtn);
coinManager.attach(pSubject);
do
{
cin >> keyPress;
if (keyPress == 'C')
coinReleaseBtn.press();
else if (keyPress == 'D')
dispenseBtn.press();
} while (keyPress != 'Q');
return EXIT_SUCCESS;
} |