Взаимодействие между DLL - PullRequest
1 голос
/ 20 июля 2009

У меня есть DLL, скажем, A, которая реализует общие алгоритмы для решения математических уравнений. У меня есть другая DLL, скажем, B, которая реализует математические уравнения DLL B использует DLL A для решения своих уравнений, но DLL B должна иметь возможность выполнять данное уравнение из DLL A (DLL A реализует некоторые числовые методы приближения и «пробует» различные значения в данном уравнении в качестве шагов к желаемому математическому решение) Теперь DLL A должна «знать» DLL B и наоборот.

Это «плохой» дизайн? Могу ли я подумать о таком коде, как любительский коус? Что бы вы сделали (пожалуйста, помните, что DLL A реализует общий алгоритм, который используется различными другими DLL, который реализует математические уравнения)?

Спасибо David

Ответы [ 5 ]

1 голос
/ 20 июля 2009

Эта проблема (циклическая зависимость реализаций между пакетами) именно поэтому была создана Принцип инверсии зависимостей (DIP) . Чарльз Бейли предоставил решение, которое использует DIP, чтобы сломать зависимость. Вместо того, чтобы связывать два конкретных класса непосредственно друг с другом (классы или функции, применение DIP не имеет большого значения), соедините их с абстракцией.

В этом случае у нас есть интерфейс, который определяет «математическую функцию» и используется решающей DLL. У нас также есть интерфейс, который определяет «алгоритмы решателя» и который используется функцией DLL. У нас конкретные классы / функции зависят от абстракций. В терминах C ++ это могут быть интерфейсы, и при вызове метода в DLL функции решатель передает себя функции в качестве указателя на «интерфейс решателя». Функция вызывает методы на интерфейсе решателя для обратного вызова солвера в соответствующих точках. Аналогично, у решателя есть класс, который получает указатель на интерфейс математической функции и вызывает его обратно в функцию в соответствующее время.

Книга Боба Мартина Agile Принципы, Шаблоны и Практики в C # охватывает эти принципы объектно-ориентированного проектирования, включая DIP. У него есть конкретные примеры, демонстрирующие эти принципы на практике. Хотя в книге используется C # (первое издание, использующее Java), те же принципы и методы применимы к C ++.

1 голос
/ 20 июля 2009

Кажется, что A - более старая dll, потому что она используется многими другими. Что кажется плохим, так это то, что вам нужно изменить A так, чтобы он вызывал B явно, это может указывать на то, что вы собираетесь снова и снова вносить изменения в A. Это плохая новость, потому что изменение A потребует перестройки всех остальных dll.

Вам нужно будет абстрагироваться от того, как B выполняет уравнения или как A решает уравнения, вводя обратный вызов любой формы, которую вы передаете B (виртуальный, обратный вызов, шаблон). Я пойду на B, так как A старше и, вероятно, более используется. Вот некоторый псевдокод, где Solver - это класс A, Equation - это класс B:

solver=new Solver;
equation=new Equation(&solver);

Solver должен реализовать своего рода абстрактный интерфейс. Лучшее решение зависит от вашего языка и структуры. Google для "принципа инверсии зависимости" или "внедрения зависимости".

1 голос
/ 20 июля 2009

Нет никакой причины, по которой DLL A нужно явно знать о DLL B, ей просто нужен интерфейс, чтобы иметь возможность оценивать уравнения, которые ей даны для решения.

Интерфейс может быть указан сигнатурой функции, указатель на подходящую функцию будет передан B к A, или он может быть представлен как абстрактный класс, и может быть передан указатель или ссылка на то, что на самом деле является производным экземпляром. от B до A.

Обычно не очень хорошая идея, хотя это возможно, иметь взаимозависимые библиотеки. В этом случае я не думаю, что это необходимо.

0 голосов
/ 20 июля 2009

Это неплохой дизайн, если вы реализуете шаблон обратного вызова, где DLL A публикует интерфейс обратного вызова, а DLL B реализует метод обратного вызова в соответствии с интерфейсом и предоставляет указатель на него при вызове A.

  • Обратный вызов процесса для длительно выполняющейся функции является распространенным использованием этого шаблона.
  • Кооперативные сопрограммы, такие как решатель, с алгоритмами обратного вызова, внедряющими кандидатов (возможно, совпадающие с другим интерфейсом), являются другим распространенным примером.
0 голосов
/ 20 июля 2009

Хороший вопрос.Да, это был бы плохой дизайн.Два решения:

  • Поместите все в одну и ту же DLL
  • Разделите A на две библиотеки DLL (одна часть, которая используется B, и другая часть, которая использует B)

Вы можете найти больше по этой теме, используя Google для «циклической» и / или «ациклической» «зависимости».

...