6

I need help understanding loose coupling. How does one design a class that uses composition to be loosely coupled, when a child object needs to communicate with their parent object? Let me give an example:

We have this:

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

How does the B object call the function foo() from its container class A? The obvious answer is "just pass a pointer from A to the b", but this is tight coupling, and an inflexible design.

Can you please give me a simple solution to this problem (in C++ or Java preferably) or provide design techniques that deal with these kinds of problems?

My real life example comes from developing a game engine for a JRPG. I have this class:

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);
};

In every game loop Update() of StateMachine is called, which calls the Update() function of curState. I want to make curState is able to call ChangeCurState from the StateMachine class, but with loose coupling.

4

6 回答 6

6

您可以使用接口解耦。

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

于 2013-08-16T16:02:08.883 回答
2

在这种情况下减少耦合的一种方法是为将在组合中使用的对象定义接口。这确保了只要它们支持您定义的接口,对其实现的任何更改都不会破坏任何东西。如果您依赖接口进行组合,您会发现您始终可以更改您的实现而不会破坏您的其他类。

于 2013-08-16T15:58:02.483 回答
1

Given your update I'll give you a different answer.

I can think of four options

  1. Pass an instance of StateMachine into each State and don't worry about it. This does couple them together but it could be argued they are tightly related anyway.

  2. As has been mentioned create an interface which just contains the methods on StateMachine that you want to be visible to State and pass this into State. This is an improvement as you now limit what State can do to your StateMachine class.

  3. Also mentioned is the use of Observer/Observable. Here your State would create events and fire them to all observers. In this case your StateMachine would have to observe all your States and react accordingly. This is perfectly valid but probably a little overcomplicated, certainly to start with.

  4. Another approach is to use something like an EventBus, created by the StateMachine and passed into each State. The State can fire events onto the event bus. The StateMachine can listen to events on the event bus and react accordingly. This is a simplification of the Observer pattern.

于 2013-08-16T16:27:10.043 回答
0

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

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

于 2013-08-16T15:59:36.713 回答
0

想想你的设计。A 和 B 如何相关,即如果 B 是 A 的一部分,那么组合就可以了。基本上,您可以通过几种方式访问​​其他类 1. 通过传递引用 2. 组合/继承 3. 朋友类

于 2013-08-16T16:06:42.657 回答
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);
    ...
}
于 2013-08-16T16:02:50.947 回答