组合物松散耦合

时间:2013-08-16 15:51:38

标签: c++ oop

我需要帮助理解松耦合。如何设计一个使用的类 当子对象需要通信时,组合要松散耦合 与他们的父对象?让我举个例子:

我们有:

class A {
    private:
        B b;
    public:
        void foo();
};

B对象如何从容器类A调用函数foo()?显而易见的答案是“只是将指针从A传递给b”,但这是紧密耦合,而且设计不灵活。

你能给我一个解决这个问题的简单方法(最好用C ++或Java) 或提供处理这些问题的设计技巧?

我的真实案例来自为JRPG开发游戏引擎。我有这门课:

class StateMachine
{
    private:
        std::map<std::string, State*> states;
        State* curState;
    public:
        StateMachine();
        ~StateMachine();
        void Update();
        void Render();
        void ChangeCurState(const std::string& stateName);
        void AddState(const std::string& stateName, State* state);
};

Update()的每个游戏循环StateMachine中调用Update(),调用curState的{​​{1}}函数。我想让curState能够致电ChangeCurState StateMachine类,但松耦合。

6 个答案:

答案 0 :(得分:6)

您可以使用接口解耦。

创建一个实现F方法的接口foo()并将其传递给B.让工具F。现在b可以在F上调用foo()而不知道甚至关心它是由A实现的。

答案 1 :(得分:2)

在这种情况下减少耦合的一种方法是为将在合成中使用的对象定义接口。这可确保对其实现的任何更改都不会破坏任何内容,前提是它们支持您定义的接口。如果你依赖于组合的接口,你会发现你总是可以在不破坏其他类的情况下改变你的实现。

答案 2 :(得分:1)

鉴于您的更新,我会给您一个不同的答案。

我可以想到四个选项

  1. StateMachine的实例传递到每个State,不要担心。这确实将它们结合在一起,但可以说它们是密切相关的。

  2. 如上所述,创建一个界面,其中只包含您希望StateMachine可见的State上的方法,并将其传递给State。这是一项改进,因为您现在限制State可以对StateMachine课程执行的操作。

  3. 还提到了Observer / Observable的使用。在这里,State会创建事件并将其发送给所有观察者。在这种情况下,您的StateMachine必须遵守所有State并做出相应的反应。这是完全有效的,但可能有点过于复杂,当然要从一开始。

  4. 另一种方法是使用由EventBus创建并传递到每个StateMachine的{​​{1}}之类的内容。 State可以将事件激发到事件总线上。 State可以监听事件总线上的事件并做出相应的反应。这是观察者模式的简化。

答案 3 :(得分:0)

如果A使用B,则可以将其包含在内部。当B需要A正常工作,然后两个对象耦合时,就会出现问题。相反,你应该尝试只传递一些值或引用B而不是整个对象。

如果绝对需要B中的整个A对象,请重构代码。

答案 4 :(得分:0)

也许是这样的(Java):

public interface A {
    void foo();
}

public interface B {
    ...
}

public class BImpl implements B {
    public B(A a) { ... }
    ...
}

public class AImpl implements A {
    private B b = new BImpl(this);
    ...
}

答案 5 :(得分:0)

考虑一下你的设计。 A和B如何相关,即如果B是A的一部分,那么组合就可以了。基本上,您可以通过几种方式访问​​其他课程 1.通过参考 2.组成/继承 3.朋友班