C ++在每个其他类中使用(通信)对象

时间:2016-06-13 07:32:46

标签: c++ design-patterns

我最近创建了一个“通信”对象/抽象类,我可以在其上使用这些函数: “发送”,“接收”,“调试发送”等。

现在,我想在基本上所有其他类中使用此对象,以便我可以使用它来发送调试消息。

目前我必须这样做:

#include "../communication/ICommunication.hpp"
extern Communication* comm;

在我想要使用此对象的任何其他文件/类中。 虽然这看起来效果很好,但我想知道是否有更简洁的方法来做到这一点。

我相信有一个软件模式,虽然我不记得名称,也没有实现。我相信,模式的名称是一个人的姓氏。

我想知道这个模式的名称(或任何有利于此目的的模式),所以我可以自己尝试实现。 如果可能的话,还有一些关于为什么这种模式比“包含和外部”代码更好的论据。

2 个答案:

答案 0 :(得分:2)

  

我想知道这个模式的名称(或任何有利于此目的的模式),所以我可以自己尝试实现。如果可能的话,还有一些关于为什么这种模式比“包含和外部”代码更好的论据。

目前使用的最佳实践是界面抽象和依赖注入:

首先抽象您要在comm对象上使用的操作:

struct Communicator
{
    virtual void send(const std::string&) = 0;
    virtual std::string receive() = 0;
    // etc
};

// injectable Communicator implementation that does nothing; this is useful as
// a default argument for code that uses communicators: it will show the dependency 
// explicitly, but setting it as a default argument ensures that client code
// doesn't _have to_ use a communicator, if you don't have one available
struct NoOpCommunicator: Communicator
{
    void send(const std::string&) override {}
    std::string receive() override { return {}; }
} dummy_communicator; // <--- notice this global

客户代码:

class YourClientCode // (uses a Communicator)
{
public:
    YourClientCode(Communicator& c = dummy_communicator) // communicator instance,
                                                         // dependency injected here
    : com(c)
    {   
    }
private:
    void f() { com.send("f()"); /* ... */ }

    Communicator& com;
};

auto client1 = YourClientCode{};
auto client2 = YourClientCode{ GetActualCommunicatorReference() };

这比include + extern更好,因为它不会对通信器的依赖性进行硬编码,并且不强制为了使用客户端代码而你必须启动并运行通信器。这大大提高了代码的可测试性和可重用性。

答案 1 :(得分:1)

这种模式叫做singleton(通常称为反模式)。它应该如下所示:

struct MySingleton {
static MySingleton& getInstance() {
   static MySingleton singleton;
   return singleton;
}
};

更好的方法是将Communication实例作为构造函数的参数传递给每个类。您也可以将其包装到shared_ptr中,这样一旦所有类都不再引用它,将自动调用Communication对象的析构函数。

  

如果可能的话,还有一些争论为什么这种模式比&#34; include和extern&#34;更好?代码。

我认为您可能遇到的一个问题是如何管理您的通信对象生存期。它应该在第一次使用之前创建,我想它应该在任何其他类或函数可能想要使用它之后销毁。

我不确定singleton是否适用于Communication对象,我假设您使用它与服务器建立连接,并在一段时间后断开连接。这可以用西格尔顿来完成,但根据我的经验,单身人士更多地用于生命周期更长的物体,比如整个应用期间。