Recently, I've tried to exercise Mediator pattern, but my program throws two exceptions. One tells me that there's some problem with empty value, and another one says that there's some problem with "this". What am I doing wrong here? I've encountered some issues with calling method "Notify" with "this" pointer because of "shared_ptr" arguments, so I used enable_shared_from_this.
#include <iostream>
#include <memory>
class IComponent;
class IMediator
{
public:
virtual void Notify(std::shared_ptr<IComponent> component, std::string task) = 0;
};
class IComponent
{
protected:
std::shared_ptr<IMediator> m_mediator;
public:
IComponent(std::shared_ptr<IMediator> mediator = nullptr) : m_mediator{ mediator } {}
void setMediator(std::shared_ptr<IMediator> mediator)
{
m_mediator = mediator;
}
};
class ConcreteComponent1 : public IComponent, std::enable_shared_from_this<ConcreteComponent1>
{
public:
void DoFirst()
{
m_mediator->Notify(shared_from_this(), "A"); //Exception thrown here
}
void DoSecond()
{
m_mediator->Notify(shared_from_this(), "B");
}
};
class ConcreteComponent2 : public IComponent, std::enable_shared_from_this<ConcreteComponent2>
{
public:
void DoThird()
{
m_mediator->Notify(shared_from_this(), "C");
}
void DoFourth()
{
m_mediator->Notify(shared_from_this(), "D");
}
};
class ConcreteMediator : public IMediator, std::enable_shared_from_this<ConcreteMediator>
{
private:
std::shared_ptr<ConcreteComponent1> m_comp1;
std::shared_ptr<ConcreteComponent2> m_comp2;
public:
ConcreteMediator(std::shared_ptr<ConcreteComponent1> comp1, std::shared_ptr<ConcreteComponent2> comp2) : m_comp1{ comp1 }, m_comp2{ comp2 }
{
m_comp1->setMediator(shared_from_this());
m_comp2->setMediator(shared_from_this());
}
virtual void Notify(std::shared_ptr<IComponent> component, std::string task)
{
if (task == "A")
{
std::cout << "Mediator reacts on A. \n";
m_comp1->DoFirst();
}
if (task == "B")
{
std::cout << "Mediator reacts on B. \n";
m_comp1->DoSecond();
}
if (task == "C")
{
std::cout << "Mediator reacts on C. \n";
m_comp2->DoThird();
}
if (task == "D")
{
std::cout << "Mediator reacts on D. \n";
m_comp2->DoFourth();
}
}
};
int main()
{
std::shared_ptr<ConcreteComponent1> comp1 = std::make_shared<ConcreteComponent1>();
std::shared_ptr<ConcreteComponent2> comp2 = std::make_shared<ConcreteComponent2>();
std::shared_ptr<ConcreteMediator> med = std::make_shared<ConcreteMediator>(comp1, comp2);
comp1->DoFirst();
}