0

请看一下代码示例。

  1. A.dll 将使用 B.dll 中的 B 类
  2. b 是 A 类的私有成员

现在,有一个模块C(C.dll或C.exe),C可以访问模块A但不能访问模块B。但是我们希望C可以调用B的方法,我该如何调整我们的设计来接近它?

  • 我们无法修改 B.dll,因为它是第 3 方模块

  • 我们可以对A类做一些改变,我们不想暴露A中的2个方法来直接调用B方法(我认为这不是一个好的设计)

    A::B_methods1() { b->B_methods1() }

    A::B_methods2() { b->B_methods2() }

  • 而且我们也不想直接暴露私有数据成员 b,例如

    const B* A::getB() { return b; }

有什么想法吗?多谢。

添加一些评论:

构建B的实例非常复杂(或者需要一些特殊的参数)。我们只能使用A来构建B。所以,如果C要访问/调用B的函数,C必须通过A来使用。

Module A.dll

class A
{
public:
    A ();
    virtual ~A();

private:
    B* b; 

}

Module B.dll

#ifdef SDK_DLL
#define HLAPI __declspec(dllexport)
#else
#define HLAPI __declspec(dllimport)
#endif

class HLAPI B
{
public:
    B ();
    virtual ~B();

public:
    B_method1();
    B_method2();
}
4

2 回答 2

1

我认为当您调用类 A 的方法时,直接调用其私有成员 B 的方法,这不是一个糟糕的设计,因为 B 只是提供一种服务,而 A 使用它,但隐藏了用法。当您使用提供例如邮件功能的库时,也会发生这种情况 - 这是正常的。

但是,我建议在第 3 方模块 B 上引入适配器外观- 这使它保持可交换性,允许您对 B 进行更多抽象,并让您还可以引入一些额外的方法。使用“无处不在”的直接调用将第 3 方模块绑定到您的代码时要小心——API 发生变化,这可能会导致大量维护工作。但也请记住,您不应该封装所有内容——尤其是具有数千个函数的 API。

我知道这些决定并不容易,因为它们最终会导致大量工作(或时间/金钱损失),所以请保持下巴;-) 顺便说一句。如果您还没有它们,我真的可以推荐书籍“设计模式”(Gamma 等人的)、“企业模式”(Fowler 的)和“Effective C++”(Meyers 的)。

*约斯特

于 2013-07-16T07:25:35.923 回答
0

让我们考虑一下语言提供的可能性

  1. 暴露 B 成员(由于问题限制,不可行),
  2. 让 C 成为 A 的朋友(我认为这也不可行,而且我知道这是非常好的)
  3. 使 B 成为 A 的受保护成员并从 A 私下派生 C
  4. 提供访问功能,或其他方式来获得 A 对 B 执行所需的操作(复合访问功能,通过外观/适配器进行抽象)。

我会选择 1 和 4 的混合。我会将 A 的 B 成员隔离到具有外观/适配器接口的“代理”对象中,然后公开该对象而不是公开 B 本身。

如果您向我们提供有关 A、B 和 C 语义的更多详细信息,所有这些将更适合您的需求。

希望能有所帮助。

于 2013-07-16T07:38:29.143 回答