请查看代码示例。
现在,有一个模块C(C.dll或C.exe),C可以访问模块A但无法访问模块B.但是我们希望C可以调用B的方法,我怎么能调整我们的设计到接近那个?
我们无法修改B.dll,因为它是第三方模块
我们可以对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();
}
答案 0 :(得分:1)
我认为当你调用类A的方法直接调用其私有成员B的方法时,它的设计并不错,因为B只是提供一种服务而A使用它,但隐藏了用法。当您使用提供例如图书馆的库时也会发生这种情况邮件功能 - 这很正常。
但是,我建议在第三方模块B上引入adapter或facade - 这样可以保持可交换性,允许你在B上有更多的抽象,让你也介绍一些其他方法。 小心使用“无处不在”的直接调用将第三方模块绑定到您的代码 - API更改,这可能会导致大量维护工作。但请记住,您不应该封装所有内容 - 尤其是不具备数千个函数的API。
我知道这些决定并不容易,因为它们最终会造成大量工作(或浪费时间/金钱),所以请保持下巴;-) 顺便说一句。如果你还没有,我可以推荐“设计模式”(Gamma等人),“企业模式”(Fowler)和“Effective C ++”(Meyers)。
*斯特
答案 1 :(得分:0)
让我们考虑语言提供的可能性
我会选择1和4的混合。我会将A的B成员隔离成带有facade / adapter接口的“proxy”对象,然后暴露这个对象而不是暴露B本身。
如果您向我们提供有关A,B和C语义的更多详细信息,那么所有这些都将更适合您的需求。
希望得到一些帮助。