跨类共享配置对象的最佳方法是什么?

时间:2011-07-11 17:09:14

标签: c++

让我们说我有M,A,B,C类.M是我的应用程序的主要类(这是完成大部分工作的那个)并具有这种结构

class M {
  public:
    // Something here.
  private:
    Conifg config;
    A a;
    std::vector<B> bs;
    const C* c;
};

在一个主要内容中,我创建了一个M类的实例m,我想设置我的配置对象,比如从文件中读取它。配置对象没什么特别的,它可以是协议缓冲区或简单的结构。

现在,我希望a,b和c能够访问配置对象,因为它们需要一些全局设置。这些设置是全局的,它们不会改变,并且对于A,B和C(和M)的每个实例都是相同的。我目前正在做的是在每个类A,B和C中都有一个静态字段,我正在为这些类的每个实例设置一个配置对象的副本。我不希望这些类知道M.的存在。这是最好的解决方案吗?我是否应该考虑全局配置变量?

4 个答案:

答案 0 :(得分:9)

只需将Config对象传递给A,B和C构造函数(具体而言,将引用传递给存储在M中的Config对象。

这会给你:

  • 可测试性(您可以轻松地换出配置对象以进行测试)
  • 易于重用(你没有必须存在的全局变量的“不可见”依赖。所有A,B和C需要存在就是它们在构造函数中给出的内容
  • 灵活性(如果需要,可以创建不同的配置对象以传递给不同的类)
  • 可读性,因为阅读代码的人不必怀疑“配置对象来自哪里?还有谁可能改变了它?我能确定它已经在此时被初始化了吗?”。 A,B和C类是自包含的,可以单独阅读和理解。

但无论你做什么,don't use a singleton,并试图避免一般的静态/全局数据。

答案 1 :(得分:4)

我建议您使用额外的静态类进行配置,而不是在所有类中使用静态字段,其中将标题包含在您想要的位置。

实现一个静态构造函数,在其中初始化静态成员中所需的所有数据。我认为这将是一个更好的解决方案。

答案 2 :(得分:4)

我个人宁愿以某种方式将该配置对象传递给A B C而不是使用全局/静态对象。 在构建b c时将它(它的引用)作为参数传递,或者稍后通过set_config()调用设置它?

答案 3 :(得分:3)

我发现这些问题的可维护解决方案最多,都是使用静态函数。如果使用某个对象接口,请将其隐藏在这些功能后面。

这是一个例子。

namespace config {
    // public interface that is used a lot
    bool GetConfigValue(const std::string &key, std::string &val);
}

namespace config {
namespace detail {

    // detail interface that is used for setup and tear down

    class Config {
    public:
        virtual ~Config() {}
        virtual bool get(const std::string &key, std::string &val) = 0;
    };

    void RegisterConfig(Config *cfg);
    void ResetConfig();
}}

老实说,你最终必须改变界面,而且它会很糟糕。您在整个代码中暴露的越多,风险就越高。所以保持简单。

作为背景,这是一个cross-cutting concern,通常很难处理。你真的不想把这些东西传递给你的对象。面向方面编程的研究可能很有趣,因为他们经常谈论这个主题。