Push versus Pull

One big problem with the Observer pattern that we have looked at so far is that the Update method in the base class is limited. In our case, it can only be used with Observers that expect two floats. If we want a different style of Observer, we need to create a new Observer class and a new Subject to work with it.

This Push version of the pattern is great because the classes are completely decoupled. The derived classes don't need to know about each other at all. The price to pay for this decoupling is that we need to write lots of Subject and Observer base classes for each method signature we want to use. An alternative version of this pattern lets the Observers pull the data they want from the Subject. In the Pull version, the Subject sends itself as a parameter in the Update method, and the Observer uses Getter methods from the Subject to only pull the data it wants.

That is exactly what is happening in our next example. The PlayerHealthBar class now takes a pointer to a Subject. In this case, we are expecting the Subject to be of type Player. The Update method can then use any Player data it needs to complete its task:

//Now the update method takes a pointer to the subject 
class Observer
{
public:
virtual ~Observer(void) {}
//Pull version of the Observer Pattern
virtual void Update(Subject* pSubject) = 0;
};

//Example of an Observer Update method that pulls data
void PlayerHealthBar::Update(Subject* pSubject)
{
//Make sure we have a Player
Player* pPlayer = dynamic_cast<Player*>(pSubject);
if(pPlayer == 0)
return;

m_percent = (pPlayer->GetHealth() / pPlayer->GetMaxHealth());
m_percent *= 100.f;

if (m_percent >= 75.0f)
m_color = "Green";
else if (m_percent < 75.0f && m_percent > 35.0f)
m_color = "Yellow";
else
m_color = "Red";
}

In the Pull version of the pattern, the Observer is dependent on the derived Subject class (in this case the Player), but the Update method is more flexible. Additionally, this Observer could be observing many different Subjects. The Update method could have a series of if statements to determine which of the many possible Subjects performed the call. The classes are more tightly coupled to specific objects. However, since an Observer can now observe multiple Subjects, the same Observer class can be used for a wider range of objects. For example, a single Observer class could be used to keep track of how many objects of each type in the game have died by registering itself with every game object that gets created and monitoring the health of all Subjects.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.151.107