Разделение UI и логики в C#

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

(Visual Studio 2008 Professional, c#, приложения для Windows).

большое спасибо.

8 ответов


поместите свою логику в отдельную сборку; и создайте эту сборку без ссылки на какие-либо пакеты GUI (например,System.Drawing, System.Windows.Forms, etc.).


Это просто вопрос практики и самодисциплины. Мы все это делали. И мы все продолжаем делать это время от времени при неправильных условиях (менеджер/клиент орет, чтобы что-то сделать "прямо сейчас" и "право" и т. д.).

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

другой подход (как упоминал Крисв, пока я печатаю) заключается в разработке логики сначала в библиотеке классов без пользовательского интерфейса. Поместите туда столько логики, сколько сможете (используйте свое суждение о том, что определяет "логику"), которая не зависит от библиотек на основе пользовательского интерфейса. Затем создайте UI, чтобы использовать это логика. Существуют различные подходы, позволяющие одновременную разработку этих двух частей, таких как тушение логической сборки за интерфейсными классами и просто кодирование частей пользовательского интерфейса к этим интерфейсам (затем использование инъекции зависимостей для подключения классов сборки к интерфейсам) и т. д.


вам нужно изучить шаблоны дизайна, такие как:

Модель-Вид-Контроллер (в MVC) часто используется на веб-сайтах (ASP.NET)
Модель-Представление-Представление-Модель (MVVM) часто используется WPF

сохраняя один из них, вы должны иметь возможность держать различные части вашего приложения отдельно.

есть другие шаблоны, которые выполняют аналогичную работу.

кроме того, разработка с помощью WPF может помочь, поскольку пользовательский интерфейс определяется XAML и код, который выполняет работу на C#. Это может обеспечить базовую степень разделения. Если вы пишете код C#, который просто манипулирует пользовательским интерфейсом, вы можете сделать шаг назад и подумать: "должен ли я делать это в XAML?". Очевидно, что могут быть вещи, которые вы должны сделать в коде позади, но это начало.


архитектура 3 слоев-это то, что вы ищете.

вы создаете 2 многоразовых слоя:

  • уровень доступа к данным (DAL) который содержит только код, необходимый для чтение/запись из базы данных
  • уровень бизнес-логики (BLL), который потребляет даль, содержит бизнес правила, проверка и предоставляет фасад для использования пользовательского интерфейса

затем в вашем UI-проекте ваша ссылка на многоразовые слои и обрабатывает только определенный пользовательский интерфейс. Проект UI разговаривает только с BLL, без прямого подключения к DAL:

UI BLL DAL

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


узнайте, как писать классы контроллеров, которые могут быть привязаны к форме и как выполнять привязку данных. В WinForms это в основном сводится к интерфейсам INotifyPropertyChanged и IDataErrorInfo в классе контроллера и использованию экземпляров BindingSource в классе формы.

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

Это основа всех конструкций MVC/MVVM.

Херби


одним словом, это называется рефакторинг.

есть только несколько причин, чтобы поместить код в пользовательский интерфейс:

  1. взаимодействия с элементом управления на форме
  2. проверка хотя это может быть помещены в слой бизнес-логики, но Обычно я добавляю вспомогательный метод в UI (намного проще)

весь другой код "бизнес-логики" переходит в другой класс, называемый классом бизнес-логики. Весь код взаимодействия с базой данных переходит в другой класс, называемый классом доступа к данным.

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

проверьте некоторые книги Мартина Фаулера по рефакторингу, такие как"рефакторинг: улучшение дизайна существующего кода". Еще одно модное слово-разделение забот. Я знаю, что вы можете сделать все это в одном классе, но код становится гораздо более читаемым и легче отлаживать, когда он разделен на классы, как я описал выше.


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

а для сохранения логики отдельная; определить, каковы ключевых компонентов и оптимизация их в том, что вспомогательный класс, способ. Например; если я обрабатываю GridView для обновления записей на основе того, выбраны они или нет; и если они выбраны, обновите ShipDate в форме; я бы сначала выяснил, выбрана ли строка; затем извлеките поле Id, затем ShipDate, а затем передайте Id и ShipDate в метод моего вспомогательного класса, который выполняет всю работу.

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


вы должны посмотреть на следующие шаблоны:

MVC (Model-View-контроллер) MVVM (Model-View-View-Model) - в основном используется в WPF с богатой поддержкой привязки данных. MVP (Model-View-Presenter) - часто используется для WinForms и веб-приложений (из-за представления без состояния)

проверьте это сообщение в блоге, которое дает пример того, как использовать MVP для питания веб-и WinForms view с одним ведущий: http://www.cerquit.com/blogs/post/MVP-Part-I-e28093-Building-it-from-Scratch.aspx

кроме того, еще одно сообщение в блоге здесь описывает использование шаблона MVP для модульного тестирования вашей бизнес-логики: http://www.cerquit.com/blogs/post/Model-View-Presenter-Part-II---Unit-Testing.aspx