обходя циклические ссылки в Delphi [дубликат]

15
задан menjaraz 13 January 2012 в 15:42
поделиться

6 ответов

Я поддерживал около миллиона строк устаревшего кода в течение последних 10 лет, поэтому я понимаю вашу боль!

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

В этой ситуации (когда мне повезет!) я могу аккуратно извлечь эти части кода в новый модуль C, содержащий константы , определения типов и общий код. Затем модули A и B используют модуль C.

Я публикую вышеизложенное с некоторой неуверенностью, потому что я не эксперт в разработке программного обеспечения и понимаю, что здесь есть много других, которые гораздо более осведомлены, чем Да. Надеюсь, мой опыт будет вам полезен.

43
ответ дан 30 November 2019 в 23:50
поделиться
  1. Похоже, у вас довольно серьезные проблемы с дизайном кода. Помимо многих признаков таких проблем, один из них - это круговые ссылки на единицу. Но, как вы сказали, вы не можете реорганизовать весь код.
  2. Перенести все возможное в раздел РЕАЛИЗАЦИЯ. Им разрешено иметь циклические ссылки.
  3. Чтобы упростить задачу (2), вы можете использовать сторонние инструменты. Я бы порекомендовал - Peganza Pascal Analyzer ( http://www.peganza.com ). Будет предложено, что вы можете перейти в раздел реализации. Это даст вам гораздо больше советов по улучшению качества вашего кода.
14
ответ дан 30 November 2019 в 23:50
поделиться

Есть много способов избежать циклических ссылок.

  1. Делегаты. Слишком часто объект выполняет некоторый код, который должен выполняться в событии, а не самим объектом. Будь то потому, что программист, работавший над проектом, был слишком короток по времени (не всегда ли?), Не имел достаточного опыта / знаний или просто ленился, какой-то такой код в конечном итоге попадает в приложения. Пример из реального мира: компонент TCPSocket, который напрямую обновляет некоторый визуальный компонент в MainForm приложения вместо того, чтобы основная форма регистрировала процедуру «OnTCPActivity» в компоненте.

  2. Абстрактные классы / интерфейсы. Использование любого из них позволяет устранить прямую зависимость между многими устройствами. Абстрактный класс или интерфейс могут быть объявлены отдельно в своем собственном модуле, ограничивая зависимость до максимума. Пример: в нашем приложении есть форма отладки. Он используется практически во всем приложении, поскольку отображает информацию из различных областей приложения. Хуже того, каждая форма, которая позволяет отображать форму отладки, также потребует всех модулей из формы отладки. Лучшим подходом было бы иметь форму отладки, которая по существу пуста, но имеет возможность регистрировать «DebugFrames».

    TDebugFrm.RegisterDebugFrame (Frame: TDebugFrame);

    Таким образом, TDebugFrm не имеет собственных зависимостей (кроме класса TDebugFrame). Любой модуль, которому требуется отображать форму отладки, может сделать это, не рискуя добавить слишком много зависимостей.

Есть много других примеров ... Бьюсь об заклад, он мог бы составить отдельную книгу. Спроектировать чистую иерархию классов с минимальными затратами времени довольно сложно, и для этого нужно иметь опыт. Знание доступных инструментов и способов их использования - это первый шаг к достижению этой цели. Но отвечая на ваш вопрос ... На ваш вопрос не существует универсального ответа, его всегда следует рассматривать в индивидуальном порядке.

7
ответ дан 30 November 2019 в 23:50
поделиться

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

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

Если у вас есть конкретный случай, когда вы думаете, что не можете избежать циклических ссылок, отредактируйте свое сообщение и предоставьте код; Я уверен, что кто-то здесь может помочь вам выяснить, как это исправить.

9
ответ дан 30 November 2019 в 23:50
поделиться

Аналогичный вопрос: Delphi Enterprise: как я могу применить шаблон посетителя без циклических ссылок?

Решение, представленное Уве Раабе, использует интерфейсы для разрешения циклической зависимости.

4
ответ дан 30 November 2019 в 23:50
поделиться

Обозреватель кода Modelmaker имеет действительно хороший мастер для перечисления всех вариантов использования, включая циклы.

Это требует компиляции вашего проекта.

Я согласен с другими плакатами, что это проблема дизайна.
Внимательно посмотрите на свой дизайн и удалите неиспользуемые блоки.

На DelphiLive'09 я провел сеанс под названием Умный код с базами данных и элементами управления с учетом данных , который содержит довольно много советов по хорошему дизайну (не ограничиваясь приложениями БД).

- jeroen

1
ответ дан 30 November 2019 в 23:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: