我正在为我的项目设计某种观察者模式,问题是我不希望我的Observee
派生类暴露给公共它的方法,如attachObserver(...)
或detachObserver(...)
。
只有我的“观察者”类需要访问这些方法。
我举个例子:
template <typename O>
class Observee {
public:
std::set<O*> getObservers() const;
virtual void attachObserver(O* observer);
virtual void detachObserver(O* observer);
private:
std::set<O*> m_Observers;
};
class SomeObserveeClass : public Observee<SomeObserverClass> {
}
(在我的案例中我不需要Observer
课程,因为我的所有“观察员”(我传递给Observee模板的课程)都没有太多共同点。
我希望SomeObserveeClass
不会公开它的Observee
方法(attachObserver
,detachObserver
)。唯一需要访问它们的类是“Observer”(Observee模板类)
我提出的唯一解决方案是私有化attachObserver
和detachObserver
并让所有Observee
成为他们各自的“观察者”的朋友,但这对我来说听起来不对。
有什么想法吗?
答案 0 :(得分:0)
我提出的唯一解决方案是私有化
attachObserver
和detachObserver
并让所有Observee
成为他们各自的“观察者”的朋友,但这对我来说听起来不对。
这就是friend
的用途。去做就对了。没有理由对增强封装感到不好。
如果您担心增加耦合,请考虑这一点:每个Observee
类(即每个模板实例化)已经耦合到其O
类。 friend
声明不会添加尚未存在的依赖项。
template <typename O>
class Observee {
public:
// ...
private:
friend O;
void attachObserver(O* observer);
void detachObserver(O* observer);
std::set<O*> m_Observers;
};
需要注意的是O
现在也可以直接访问m_Observers
。你必须决定这是否值得。
对我的代码感到奇怪的是,attachObserver
和detachObserver
是virtual
。这是为什么?它们意味着在m_Observers
容器上运行,该容器只能在基类中访问。派生类的实现如何不同呢?一个函数添加到集合中,另一个函数从中删除。这不是一个明智的定制点。
所以只需将函数设为非 - virtual
。这也将非继承友谊问题转变为非问题。
您的示例中缺少某种notifyObservers
函数。它应该是protected
,非 - virtual
。
答案 1 :(得分:0)
无法使用C ++。与Java语言不同,没有可用的包范围,因此请使用友元类或公开其功能。
如果您想限制范围,可以使用 命名空间 。
在这种情况下使用模板对我来说没有意义,因为模板目标是重用与任何类型无关的相同算法。
如果需要向层次结构添加特定功能,只需使用类。