我正在用 C++14 开发一个 EventSystem 类,旨在合并观察者模式。我设计的一个关键方面是确保与各种容器类型的兼容性,例如 std::vector、std::map 等,从而增强其灵活性和可扩展性。我的策略涉及利用模板来实现这一目标。
这是我当前实施的概述:
#include <iostream>
#include <vector>
#include <map>
template<typename MessageType,typename ObserverType, typename InfoType, typename ContainerType>
class EventSystem : public Subject<MessageType, ObserverType, InfoType>
{
public:
// static_assert("ContainerType must be a subtype of IContainer");
virtual ~ EventSystem() = default;
private:
ContainerType mContainer;
void Attach(const InfoType& observerID, ObserverType& observer) override
{
mContainer.Add(observerID, observer);
}
void Detach(const InfoType& observerID) override
{
mContainer.Remove(observerID);
}
};
template <typename T>
class IContainer
{
public:
virtual void Add(const T& item) = 0; // Adds item
virtual void Remove(const T& item) = 0; // Remove the item if it exists in the container
virtual ~IContainer() = default;
};
template <typename T, typename ContainerType>
class Container : public IContainer<T>
{
public:
void Add(const T& item) override
{
container.Add(item);
}
void Remove(const T& item) override
{
container.Remove(item);
}
private:
ContainerType container;
};
template <typename T>
class VectorContainer
{
public:
void Add(const T& item)
{
vect.push_back(item);
}
void Remove(const T& item)
{
// Assuming T has a valid equality comparison
auto it = std::remove(vect.begin(), vect.end(), item);
vect.erase(it, vect.end());
}
private:
std::vector<T> vect;
};
template <typename Key, typename Value>
class MapContainer
{
public:
void Add(const std::pair<const Key, Value>& keyValue)
{
container.insert(keyValue);
}
void Add(const Key& key, const Value& value)
{
container[key] = value;
}
void Remove(const std::pair<const Key, Value>& keyValue)
{
container.erase(keyValue.first);
}
private:
std::map<Key, Value> container;
};
我遇到的核心挑战是IContainer接口的实现。要求是使用单个模板参数来定义它,同时允许在可能需要多个模板参数的容器类中适应此接口。这种情况对于像 MapContainer 这样需要两个参数的类尤其相关。为了解决这个问题,我正在考虑应用组合方法。
我的问题背后的目的是寻求有关构建 IContainer 接口及其在各种容器类型中的实现的建议,特别是那些需要多个模板参数的容器类型。对于实现在 IContainer 接口的通用性和复杂容器类的特定需求之间保持平衡的设计的见解将受到高度赞赏。
struct Event {
TYPE type;
virtual void Handle() = 0;
};
struct DamageEvent : Event {
float damage;
int target;
void Handle() final {
FindTarget(target).TakeDamage(damage);
}
};
void Observer::notify(Event event) {
if (/* event.type needs to be handled here */) {
event.Handle();
}