Лучший подход к модульному программированию в Delphi

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

позвольте мне опубликовать то, что я уже написал здесь.

программное обеспечение разработано компанией я работаю, состоит из более чем 100 модулей (большинство из них что-то вроде драйверов для разных устройств). Большинство из них используйте один и тот же код - в большинстве случаев классы. Проблема в том, что эти классы не всегда помещаются в отдельные, автономные единицы PAS. Я имею в виду, что общий код часто помещается в блоки, содержащие код, специфичный для модуля. Это означает, что при исправлении ошибки в общем классе недостаточно скопировать определенный блок PAS во все программные модули и перекомпилировать их. К сожалению, вам нужно скопировать и вставить фиксированные фрагменты кода в каждый модуль, один за другим, в соответствующий блок и класс. Это занимает много времени, и это то, что я хотел бы устранить в ближайшем будущем, выбрав правильный подход - пожалуйста, помогите мне.

Я думал, что использование bpls, распределенных с EXEs, было бы хорошим решением, но у него есть некоторые недостатки, Как упоминалось в предыдущем обсуждении. Худшая проблема заключается в том, что если каждый EXE нуждается в нескольких BPLs, наша служба технической поддержки должна знать, какой EXE нуждается в каких BPLs, а затем предоставить конечным пользователям соответствующие файлы. Как пока у нас нет обновления программного обеспечения, это будет очень много для наших техников и конечных пользователей. Они наверняка заблудятся и рассердятся : -/.

также могут возникнуть проблемы совместимости-если один BPL разделяется многими EXEs, модификация этого BPL может быть хорошей для одного EXE и плохой для некоторых других.

Что мне делать, чтобы исправить ошибки быстрее во многих проектах? Я думаю об одном из следующих подходов. Если у вас есть идеи получше, пожалуйста, позвольте мне знать.

  • поместите общий код в отдельные и автономные блоки PAS, поэтому, когда в одном из них есть исправление ошибки, достаточно скопировать его во все проекты (перезаписать старые файлы) и перекомпилировать их все. Это означает, что каждый блок копируется столько раз, сколько проектов она используется.

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

  • создайте BPLs для всего общего кода, но свяжите их в EXEs, чтобы EXEs были автономными.

для меня это кажется лучшим решением сейчас, но есть некоторые минусы. Если я исправлю ошибку в BPL, каждый программист должен будет обновить BPL на своем компьютере. Что, если они забудут это сделать? это? Однако, я думаю, что это незначительная проблема. Если мы позаботимся об информировании друг друга об изменениях, все должно быть хорошо. А ты как думаешь?

  • и последняя идея, предложенная CodeInChaos (я не знаю, правильно ли я ее понял). Обмен файлами PAS между проектами. Вероятно, это означает, что нам придется хранить общий код в отдельной папке и заставлять все проекты искать этот код там, верно? И всякий раз, когда необходимо изменить проект, он бы для загрузки из SVN вместе с папкой общих файлов, я думаю. Каждое изменение общего кода должно вызывать перекомпиляцию каждого проекта, использующего этот код.

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

спасибо ты очень.

2 ответов


вы говорите:

  • создайте BPLs для всего общего кода, но свяжите их в EXEs, поэтому что бывшие автономны.

вы не можете связать BPLs в исполняемый файл. Вы просто связываете в отдельных единицах, которые также находятся в BPL. Таким образом, вы на самом деле не использовать или даже нужно BPL вообще.

BPLs предназначены для использования в качестве общего кода, т. е. вы помещаете общий код в один или несколько BPLs и используйте это от каждого из них .Франко. ,библиотеки DLL или другие .bpls. Исправления ошибок (если они не изменяют открытый интерфейс BPL) просто требуют перераспределения этого фиксированного BPL.

Как я уже сказал, решите открытый интерфейс DLL, а затем не меняйте его. Ты можешь!--10-->добавить подпрограммы, типы и классы, но вы не должны изменять открытые интерфейсы любых существующих классов,типов, интерфейсов, констант, глобальных переменных и т. д. это уже в употреблении. Таким образом, Фиксированная версия BPL может быть легко распространена.

но обратите внимание, что BPLs сильно зависят от версии компилятора. Если вы используете новую версию компилятора, вам также придется перекомпилировать BPL. Вот почему имеет смысл давать суффиксы BPLs, такие как 100, 110 и т. д. в зависимости от версии компилятора. Исполняемому файлу, скомпилированному с компилятором версии 15.0, будет предложено использовать BPL с суффиксом 150, а исполняемому файлу, скомпилированному с версией 14.0, - BPL с суффиксом 140. Таким образом, различные версии BPLs могут мирно сосуществовать. Суффикс можно задать в параметрах проекта.

Как вы управляете различными версиями? Создать каталог со структурой, как у меня для моего ComponentInstaller BPL (это эксперт, которого вы можете увидеть в Delphi/C++Builder / RAD Studio XE IDE в меню компоненты - > установить компонент):

Projects
  ComponentInstaller
    Common
    D2007
    D2009
    D2010
    DXE

общий каталог содержит .pas файлы и ресурсы (растровые изображения, так далее.) общий для каждой версии, и каждый из каталогов Dxxxx содержит .ДПК .dproj и др. для этой конкретной версии BPL. Каждый из пакетов использует файлы в общем каталоге. Это, конечно, можно сделать для нескольких BPLs сразу.

системы управления версиями может сделать это намного проще, кстати. Просто не забудьте дать каждой версии BPL другой суффикс.

Если вы действительно хотите автономные исполняемые файлы, вы не используете BPLs и просто ссылаетесь на отдельные элементы. Параметр "compile with BPLs" управляет этим.


с моей точки зрения, пытаясь управлять артефактами, такими как блоки Delphi, библиотеки и исполняемые файлы, вы ищете в неправильном месте. Я предлагаю вам развернуться и начать с рефакторинга кода, на основе шаблоны проектирования реализация.

Е. Г. все общие функции могут быть помещены в одну Синглтон class, экземпляры общих классов могут быть построены с помощью Абстрактная Фабрика, классы могут взаимодействовать через собственный Delphi реализация интерфейсов вместо прямого использования и так далее. Даже вы можете выбрать для реализации фасад для всех общих частей проектов.

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

некоторые другие вещи:

  1. конечно, вы должны следовать предложению @CodeInChaos и делиться одной копией исходного файла между всеми проектами вместо копирования его в каждый проект вручную. Это может быть полезно, если вы примете какой-то стандарт для построения среды, который будет обязательным для всех разработчиков (та же структура папок, расположение библиотек, параметры среды).
  2. попробуйте проанализировать процесс построения и развертывания: для меня это выглядит ненормально, когда решение не построено с последняя версия кода и не протестирована перед развертыванием. (это для вашего "Если я сделаю исправление ошибки в BPL, каждый программист ..." фраза.)
  3. вариант с автономными исполняемыми файлами выглядит лучше, поскольку значительно упрощает организацию среды тестирования и развертывания проекта. Просто выберите соответствующие соглашения для управления версиями.