gpt4 book ai didi

c++ - 使用接口(interface)包装库而不需要向下转换

转载 作者:IT老高 更新时间:2023-10-28 21:55:34 25 4
gpt4 key购买 nike

假设我的项目使用了一个库 LibFoo,它通过许多类提供其功能,例如 FooAFooB。现在,有许多类似的库(例如,提供 BarABarBLibBar)提供与 LibFoo 相同的功能 并且我希望我的项目的用户能够选择使用哪个库,最好是在运行时。

为此,我创建了一个“包装层”,它定义了我期望从库中获得的接口(interface)。在我的示例中,该层包含两个接口(interface):IfaceAIfaceB。然后,对于我想要支持的每个库,我创建一个“实现层”,使用其中一个库来实现接口(interface)。

我现在的问题在于如何很好地实现实现层。为了演示我的问题,考虑我们有以下接口(interface)(用 C++ 显示,但应该适用于类似的语言):

class IfaceA
{
public:
virtual void doSomethingWith(IfaceB& b) = 0;
...
};

class IfaceB
{
...
};

LibFoo 实现层中的类将保存来自LibFoo 相应类的对象。接口(interface)中的操作应该使用这些对象来实现。因此(请原谅我的可怕名字):

class ConcreteAForFoo : public IfaceA
{
public:
void doSomethingWith(IfaceB& b) override
{
// This should be implemented using FooA::doSomethingWith(FooB&)
}

private:
FooA a;
};

class ConcreteBForFoo : public IfaceB
{
public:
FooB& getFooB() const
{
return b;
}

private:
FooB b;
};

问题在于实现 ConcreteAForFoo::doSomethingWith:它的参数类型为 IfaceB& 但我需要访问 ConcreteBForFoo 的实现细节来能够正确执行该方法。我发现这样做的唯一方法是到处使用丑陋的向下转型:

void doSomethingWith(IfaceB& b) override
{
assert(dynamic_cast<ConcreteBForFoo*>(&b) != nullptr);
a.doSomethingWith(static_cast<ConcreteBForFoo&>(b).getFooB());
}

由于不得不向下转换通常被认为是代码异味,我不禁想到应该有更好的方法来做到这一点。还是我一开始就设计错了?

TL;DR

给定一层相互依赖的接口(interface)(其中一个接口(interface)中的方法接收对其他接口(interface)的引用)。这些接口(interface)的实现如何在不向下转换或在接口(interface)中暴露这些细节的情况下共享实现细节?

最佳答案

看起来很经典double dispatch用例。

class IfaceA
{
public:
virtual void doSomethingWith(IfaceB& b) = 0;
...
};

class IfaceB
{
virtual void doSomethingWith(IfaceA & a) = 0;
...
};

struct ConcreteAForFoo : public IfaceA {
virtual void doSomethingWith (IfaceB &b) override {
b.doSomethingWith(*this);
}
};

struct ConcreteBForFoo : public IfaceB
{
virtual void doSomethingWith(IfaceA & a) override {
//b field is accessible here
}

private:
FooB b;
};

可以改变 IfaceB::doSomethingWith 签名以获得耦合和访问级别之间的最佳平衡(例如,ConcreteAForFoo 可以用作参数以通过紧密耦合来访问其内部)。

关于c++ - 使用接口(interface)包装库而不需要向下转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27224764/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com