I am trying to implement the observer pattern for a stock exchange scenario. Multiple stocks can be registered at a stock exchange. There will be stock observers who are observing some specific stocks. Please advise how this implementation can be improved.
stock_exchange.hpp
#ifndef STOCK_EXCHANGE_HPP
#define STOCK_EXCHANGE_HPP
#include "stock_observer.hpp"
#include "stock.hpp"
#include<unordered_map>
#include<string>
#include<list>
class Stock_Observer;
class Stock;
class Stock_Exchange
{
std::unordered_map<std::string, Stock*> registered_stocks;
std::unordered_map<std::string, std::list<Stock_Observer*>> stock_observers;
public:
void notify_observers(std::string stock_name);
void unregister_observer(Stock_Observer& so, std::string stock_name);
void register_observer(Stock_Observer& so, std::string stock_name);
void add_stock(Stock& new_stock);
void remove_stock(Stock& s);
Stock& get_stock(std::string stock_name);
};
#endif // STOCK_EXCHANGE_HPP
stock_exchange.cpp
#include "stock_exchange.hpp"
#include "stock_observer.hpp"
#include<algorithm>
void Stock_Exchange::add_stock(Stock& new_stock)
{
registered_stocks[new_stock.get_name()] = &new_stock;
}
void Stock_Exchange::remove_stock(Stock& s)
{
registered_stocks.erase(s.get_name());
stock_observers.erase(s.get_name()); //Memory leak!!!
}
Stock& Stock_Exchange::get_stock(std::string stock_name)
{
return *registered_stocks[stock_name];
}
void Stock_Exchange::register_observer(Stock_Observer& observer, std::string stock_name)
{
stock_observers[stock_name].push_back(&observer);
}
void Stock_Exchange::unregister_observer(Stock_Observer& observer, std::string stock_name)
{
auto l = stock_observers[stock_name];
l.erase(std::find(l.begin(), l.end(),&observer));
}
void Stock_Exchange::notify_observers(std::string stock_name)
{
for(auto o : stock_observers[stock_name])
{
o->notify(stock_name);
}
}
stock_observer.hpp
#ifndef STOCK_OBSERVER_HPP
#define STOCK_OBSERVER_HPP
#include "stock.hpp"
#include "stock_exchange.hpp"
#include<string>
class Stock_Exchange;
class Stock_Observer
{
static int id_sequence;
int id;
Stock_Exchange* se;
public:
Stock_Observer(Stock_Exchange* s)
{
se = s;
id = id_sequence++;
}
void notify(std::string stock_name);
};
#endif // STOCK_OBSERVER_HPP
stock_observer.cpp
#include "stock_observer.hpp"
#include<iostream>
int Stock_Observer::id_sequence = 1;
void Stock_Observer::notify(std::string stock_name)
{
std::cout << "Object " << id << " notified about " << stock_name << std::endl;
}
stock.hpp
#ifndef STOCK_HPP
#define STOCK_HPP
#include "stock_exchange.hpp"
#include<string>
class Stock_Exchange;
class Stock
{
std::string name;
double price;
Stock_Exchange* se;
public:
Stock(Stock_Exchange* s, std::string stock_name, double stock_price)
{
se = s;
name = stock_name;
price = stock_price;
}
std::string get_name();
void set_price(double p);
};
#endif // STOCK_HPP
stock.cpp
#include "stock.hpp"
std::string Stock::get_name()
{
return name;
}
void Stock::set_price(double p)
{
price = p;
se->notify_observers(this->name);
}
main.cpp
#include<iostream>
#include "stock_exchange.hpp"
#include "stock_observer.hpp"
#include "stock.hpp"
int main()
{
Stock_Exchange se;
Stock_Observer so1(&se), so2(&se);
Stock infy(&se,"INFY",1234.33);
Stock tcs(&se,"TCS",1100);
Stock sbi(&se,"SBI",2312.33);
se.register_observer(so1,"INFY");
se.register_observer(so2,"INFY");
se.register_observer(so1,"TCS");
infy.set_price(1250.33);
tcs.set_price(999.32);
sbi.set_price(2300.00);
}