Как вы сохраняете логику приложения отдельно от пользовательского интерфейса, когда компоненты пользовательского интерфейса имеют встроенные функции?

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

Delphi поставляется с компонентами с методами, которые делают то, что я хочу, например, компонент RichText Memo позволяет мне работать с богатым текстом. Другие компоненты, такие как строковая сетка TMS, не только делают то, что я хочу, но и оплачиваю дополнительную функциональность. Эти функции помещают R в RAD.

Кажется нелогичным писать мои собственные классы, чтобы делать то, что кто-то еще сделал для меня. Он изобретает колесо [когда-либо пытался работать напрямую с богатым текстом?:-)] Но если я использую функциональность, встроенную в такие компоненты, то в итоге у меня будет много перемешанного пользовательского интерфейса и кода домена. У меня будет форма с большей частью моего кода, встроенного в обработчики событий.

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

Ответ 1

Прежде всего, помните, что "работа с богатым текстом" - это не то, что должно делать ваше приложение. Ваше приложение должно позволить пользователю выполнить определенную задачу, а код для выполнения этой задачи - это ваша логика домена. Если часть задачи, которую требуется выполнить вашей программе, включает работу с расширенным текстом, вы можете делегировать ее часть в компонент с богатым текстом. Сложность приходит, как вы упомянули, на интерфейсе между этими библиотеками и логикой домена.

То, как логика домена Delphi и элементы управления Delphi UI взаимодействуют друг с другом, в основном, являются обработчиками событий. Но это не означает, что вам нужно поместить свою логику домена в самих обработчиков событий. Вместо этого попробуйте написать единицы, содержащие код для конкретных задач, необходимых для выполнения, и обработчики событий вызывают эти единицы.

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

Ответ 2

Вы можете создать довольно чистое разделение, используя datamodules с clientDataSets, чтобы содержать вашу бизнес-логику и объекты данных. Вы даже можете сделать шаг дальше и отторгнуть бизнес-логику от данных. Очевидно, что форма содержит пользовательский интерфейс. Почти каждый компонент, который вы используете, может быть привязан к данным, что упрощает привязку их к вашим наборам clientDataSets.

Просто помните, что у Delphi есть способ делать вещи, которые не всегда соответствуют лучшим практикам, которые есть у Java или .Net. Ваша цель должна заключаться в том, чтобы делать что-то, что кажется правильным и работает для Delphi.