Я - кто-то, кто преподавал мне программирование и не имел никакого формального обучения в программировании.NET.
Некоторое время назад я запустил C# для разработки программы GUI для управления датчиками, и проект цвел. Я просто задавался вопросом, как лучше всего организовать код, особенно код UI, в моих формах.
Мои формы в настоящее время являются путаницей или по крайней мере кажутся путаницей мне.
Моя проблема, это походит на путаницу, особенно государственная собственность, и становится неудобным в сопровождении. Кроме того, мой код прикладной логики и код UI находятся в том же файле и до некоторой степени, смешаны, который кажется неправильным и означает, что я должен сделать большую прокрутку для нахождения то, в чем я нуждаюсь.
Как Вы структурируете свои формы .NET?
Спасибо
Вот ссылка на довольно часто используемый шаблон архитектуры.
http://en.wikipedia.org/wiki/Model_View_ViewModel
Я бы также поискал некоторые другие архитектурные шаблоны и подробнее изучил этот, поискал бы пример кода и т. Д.
Существует ряд паттернов, которые помогают разделить логику в приложениях, что приводит к созданию более чистого и удобного кода. Шаблон MVP - это хороший шаблон для начала. Он основан на определении трех областей ответственности, т.е. MVP M = модель, V = представление, P = ведущий. Если вы знакомы с использованием интерфейсов, у вас все получится, в противном случае это будет хорошим началом (ознакомьтесь с основными принципами ОО: инкапсуляция, абстракция, полиморфизм). Основной принцип MVP заключается в том, чтобы поместить логику приложения в презентатор. Презентер общается с представлением (вашей формой) через интерфейс, а представление обращается к презентеру (я использую интерфейс и для этого), когда пользователь взаимодействует с ним. Модель - это иерархия доменных объектов решения, которая имплицирует логику бизнеса и отношения между сущностями.
Большинство моделей пользовательского интерфейса (MVP, MCV и т.д.) пытаются делать одни и те же вещи, разделяя ваши проблемы. Ниже приведен простой пример:
//Интерфейс представления
interface IUserDetailsView
{
string Username{set;get;}
string FirstName{get;set;}
string LastName{get;set;}
UserDetailsPresenter Presenter{get;set;}
void DisplayMessage(string message);
}
//Имплантация представления //Стандартная форма windows, которая имеет текстовые поля, метки, комбинации и т.д., которые
class UserDetailsView : Form, IUserDetails
{
public string Username{set{txtUserName.text = value;}get{return txtUserName.text;}}
public string FirstName{set{txtFirstName.text = value;}get{return txtFirstName.text;}}
public string LastName{set{txtLastName.text = value;}get{return txtLastName.text;}}
Public UserDetailsPresenter Presenter{get;set;}
public void DisplayMaessage(string message)
{
MessageBox.Show(message);
}
private void saveButton_Click(object sender, EventArgs e)
{
Presenter.SaveUserDetails();
}
}
//Логика представления
class Presenter UserDetailsPresenter {
//Constructor
public userDetailsPresenter(IUserDetailsView view)
{
//Hold a reference to the view interface and set the view's presnter
_view = view;
_view.Presenter = this;
}
private IUserDetailsView _view;
DisplayUser(string userName)
{
//Get the user from some service ...
UserDetails details = service.GetUser(userName);
//Display the data vioa the interface
_view.UserName = details.UserName;
_view.FirstName = details.FirstName;
_view.LastName = details.LastName;
}
public void SaveUserDetails()
{
//Get the user dryaiols from the view (i.e. the screen
UserDetails details = new UserDetails();
details.UserName = _view.UserName;
details.FirstName = _view.FirstName;
details.LastName = _view.LastName;
//Apply some business logic here (via the model)
if(!details.IsValidUserDetails())
{
_view.DisplayMessage("Some detail outlining the issues");
return;
}
//Call out to some service to save the data
service.UpdateUser(details);
}
}
//И наконец, модель
public class UserDetails
{
public UserName {get;set;}
public FirstName{get;set;}
public LastName{get;set;}
public bool IsValidUserDetails()
{
if(LastName == "Smith")
{
//We do not allow smiths, remember what happened last time ... or whatever
return false;
}
return true;
}
}
Надеюсь, это объясняет, как разграничивается ответственность. Форма не имеет никакой логики, кроме отображения/форматирования и т.д., ее также можно заглушить для тестирования. Ведущий является посредником между представлением и моделью и делает вызовы к сервисам, а модель реализует вашу бизнес-логику. Как уже было сказано, существуют вариации этого паттерна, которые могут сделать ваш код немного более тонким и гибким, но здесь описаны основные принципы. Надеюсь, это поможет.
:-)
В сложных формах я обычно разделяю код на отдельные файлы. Это можно сделать с помощью "частичного класса". Каждый файл исходного кода имеет имя, основанное на форме. Например, MainForm.cs, MainForm.State.cs, MainForm.Update.cs, MainForm.Menu.cs и так далее. Если у меня много сложных форм, я создам подпапку для каждой. Единственный совет здесь - создать форму MainForm.Wip.cs. Эта форма частичного класса - код, над которым вы сейчас работаете. Как только вы закончите работу с этим кодом, вы можете либо переименовать его, либо переместить код в другие файлы исходного кода.
Кроме того, я также буду создавать пользовательские элементы управления. Это дает преимущество повторного использования кода и переносит большую часть функциональности за пределы формы. Посмотрите статью "Разработка пользовательских элементов управления Windows Forms с помощью .NET Framework" на http://msdn.microsoft.com/en-us/library/6hws6h2t.aspx.
Посмотрите Nobody Cares What Your Code Looks Like на http://www.codinghorror.com/blog/2007/12/nobody-cares-what-your-code-looks-like.html. Кое-что, о чем стоит подумать перед "организацией".
Я стараюсь помещать как можно больше кода в пользовательские элементы управления или пользовательские элементы управления. Компоненты легче использовать повторно, а код формы легче читать.
Пользовательские элементы управления также могут обрабатывать и отображать события, которые могут упростить отделение динамических частей от кода формы.
Вы даже можете создавать собственные элементы управления, которые не отображаются в форме, например, таймер.
Вы должны сначала проанализировать свой код, чтобы разделить логику приложения и логику пользовательского интерфейса. Оба они никогда не должны находиться в одном файле. Свойство состояния определенно не является логикой пользовательского интерфейса, поэтому сначала удалите его из формы. Это поможет вам очистить код формы.
Во-вторых, прочтите о некоторых шаблонах проектирования и принципах. Вы можете найти несколько отличных примеров здесь , в вашем случае я бы проверил поведенческие паттерны, в частности паттерн Состояние и Посредник. Это не серебряные пули для решения ваших проблем, но они должны дать вам лучшее представление о том, как разделить ваше приложение и логику пользовательского интерфейса.
Взгляните на паттерн "Модель-Вид-Презентатор": http://en.wikipedia.org/wiki/Model_View_Presenter
Используя этот паттерн, код-бэкграунд ваших форм должен в основном содержать простые каскадные вызовы ведущего, который в свою очередь будет изменять модель, каскадируя события обратно в представление (иногда через ведущего, в зависимости от вашей реализации).
Суть в следующем: Ваши формы (представление) не должны содержать никакой информации о состоянии; она будет находиться в ведущем, и его не должно волновать, откуда он получает данные, до тех пор, пока эти данные соответствуют заданному контракту. Это повышает тестируемость, так как вы можете легко проверить ваши состояния и данные на презентере, и отделяет представление, позволяя использовать PLAFs, различные представления одних и тех же данных и тому подобное.
Удачи :)
Некоторые быстрые предложения:
Постарайтесь перенести весь ваш не пользовательский код из форм, вы хотите иметь только GUI код в реальной форме, если это возможно. Если свойство имеет побочный эффект, оно, вероятно, должно быть функцией. Ваше свойство State почти наверняка должно быть методом, и посмотрите, можете ли вы разбить код из него на отдельные методы, чтобы был только один вызов функции на состояние.