c ++如何隐藏观察者实现

时间:2017-03-25 15:59:12

标签: c++ observer-pattern

我正在为我的项目设计某种观察者模式,问题是我不希望我的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方法(attachObserverdetachObserver)。唯一需要访问它们的类是“Observer”(Observee模板类)

我提出的唯一解决方案是私有化attachObserverdetachObserver并让所有Observee成为他们各自的“观察者”的朋友,但这对我来说听起来不对。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

  

我提出的唯一解决方案是私有化attachObserverdetachObserver并让所有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。你必须决定这是否值得。

对我的代码感到奇怪的是,attachObserverdetachObservervirtual。这是为什么?它们意味着在m_Observers容器上运行,该容器只能在基类中访问。派生类的实现如何不同呢?一个函数添加到集合中,另一个函数从中删除。这不是一个明智的定制点。

所以只需将函数设为非 - virtual。这也将非继承友谊问题转变为非问题。

您的示例中缺少某种notifyObservers函数。它应该是protected,非 - virtual

答案 1 :(得分:0)

无法使用C ++。与Java语言不同,没有可用的包范围,因此请使用友元类或公开其功能。

如果您想限制范围,可以使用 命名空间

在这种情况下使用模板对我来说没有意义,因为模板目标是重用与任何类型无关的相同算法。

如果需要向层次结构添加特定功能,只需使用类。