【发布时间】:2014-11-09 22:11:06
【问题描述】:
我正在尝试创建一个观察者模式,主题通过不同的通知通知观察者。
通常在观察者模式实现中,您只能看到一个名为 notify 的方法,它通知观察者某事发生了,并且有一种反转,观察者持有主体的指针,并在收到通知时向主体询问某事.
我的实现有点不同,主体附加观察者并通知所有观察者,而不需要在观察者内部持有主体的指针。例如:
#include <iostream>
#include <vector>
class ObserverEvents
{
public:
virtual addSomethingOne(int) = 0;
virtual addSomethingTwo(float) = 0;
};
class Observer : public ObserverEvents
{
public:
Observer();
~Observer();
virtual addSomethingOne(int) {}
virtual addSomethingTwo(float) {}
};
class Subject : public ObserverEvents
{
public:
Subject() {}
~Subject()
{
for (int i = 0; i < observers.size(); ++i)
{
delete observers[i];
}
}
void attach(Observer * observer)
{
observers.push_back(observer);
}
virtual addSomethingOne(int something)
{
for (int i = 0; i < observers.size(); ++i)
{
observers[i].addSomethingOne(something);
}
}
virtual addSomethingTwo(float something)
{
for (int i = 0; i < observers.size(); ++i)
{
observers[i].addSomethingTwo(something);
}
}
private:
std::vector<Observer *> observers;
};
class FooObserver : public Observer
{
public:
BarObserver() {}
~BarObserver() {}
addSomethingOne(int something)
{
// do something with something
}
addSomethingTwo(float something)
{
// do something with something
}
};
class BarObserver : public Observer
{
public:
BizObserver() {}
~BizObserver() {}
addSomethingOne(int something)
{
// do something with something
}
addSomethingTwo(float something)
{
// do something with something
}
};
int main(int argc, char const * argv[])
{
Subject subject;
subject.attach(new FooObserver());
subject.attach(new BarObserver());
return 0;
}
我唯一担心的是,如果我没有违反任何设计原则,如 Open 和 Closed 或类似的东西,以及我是否需要添加一个我需要在所有其他类中实现的新通知。 (这很痛苦 - 想象一下 10 个甚至更多的观察者)。
我正在考虑让这个不同,只创建一个接口,然后我可以继承它来创建其他通知,但是有一个问题,观察者如何确定每种不同类型的通知是什么?
例子:
#include <iostream>
#include <vector>
class Notifier
{
public:
Notifier() {}
~Notifier() {}
virtual int getInt() const = 0;
};
class FooNotifier
{
public:
FooNotifier() {}
~FooNotifier() {}
int getInt() const
{
return 10;
}
};
class BarNotifier
{
public:
BarNotifier() {}
~BarNotifier() {}
int getInt() const
{
return 50;
}
};
class Observer : public ObserverEvents
{
public:
Observer();
~Observer();
virtual receive(Notifier *) = 0;
};
class Subject : public ObserverEvents
{
public:
Subject() {}
~Subject()
{
for (int i = 0; i < observers.size(); ++i)
{
delete observers[i];
}
}
void attach(Observer * observer)
{
observers.push_back(observer);
}
virtual notify(Notifier * notification)
{
for (int i = 0; i < observers.size(); ++i)
{
observers[i].receive(notification);
}
}
private:
std::vector<Observer *> observers;
};
class FooObserver : public Observer
{
public:
BarObserver() {}
~BarObserver() {}
receive(Notifier * notification)
{
// ...
}
};
class BarObserver : public Observer
{
public:
BizObserver() {}
~BizObserver() {}
receive(Notifier * notification)
{
// ...
}
};
int main(int argc, char const * argv[])
{
Subject subject;
subject.attach(new FooObserver());
subject.attach(new BarObserver());
subject.notify(new FooNotifier());
subject.notify(new BarNotifier());
return 0;
}
实现只是一个示例,我知道我可以使用智能指针、删除原始指针并做得更好,但这只是一个实现示例。
这种新方法的问题在于,我需要知道Notifier 的 API 是否才能在 Observer 中使用它,才能调用 getInt。
我该怎么做,最好的方法是什么?如何向观察者发送不同的通知?
【问题讨论】:
-
看来你走的是 Java 路。 Java 以自己的方式做事,是因为语言非常受限制,而不是因为它好。我们有指针、lambda 和仿函数。
-
其实我也不知道,我以前没用过Java。
标签: c++ design-patterns observer-pattern design-principles