Чтобы это работало, я создал «уровень-оболочку», который определяет интерфейсы, которые я ожидаю от библиотеки. В моем примере этот уровень содержит два интерфейса: IfaceA и IfaceB. Затем для каждой библиотеки, которую я хочу поддерживать, я создаю «уровень реализации», реализующий интерфейсы с использованием одной из библиотек.
Моя проблема теперь заключается в том, как реализовать уровень реализации хорошо. Чтобы продемонстрировать мою проблему, предположим, что у нас есть следующие интерфейсы (показаны на C++, но должны быть применимы к аналогичным языкам):
Код: Выделить всё
class IfaceA
{
public:
virtual void doSomethingWith(IfaceB& b) = 0;
...
};
class IfaceB
{
...
};
Код: Выделить всё
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;
};
Код: Выделить всё
void doSomethingWith(IfaceB& b) override
{
assert(dynamic_cast(&b) != nullptr);
a.doSomethingWith(static_cast(b).getFooB());
}
TL;DR
Дан уровень взаимозависимых интерфейсов (при этом методы в одном интерфейсе получают ссылки на другие интерфейсы). Как реализации этих интерфейсов могут совместно использовать детали реализации, не принижая и не раскрывая эти детали в интерфейсах?
Подробнее здесь: https://stackoverflow.com/questions/272 ... -downcasts
Мобильная версия