1

Я пытаюсь обернуть голову тем, как внедрить мой код: взять простую рутину и разделить ее на 5 или 6 методов в 3 или 4 классах.Что такое MVC-версия этого кода?

Я быстро подобрал три простых примера кода как я его сейчас пишу. Могла ли кто-нибудь конвертировать их в запутанную версию MVC/MVP?


Пример 1: фамилия является обязательным. Пометьте текстовое поле красным, если ничего не введено. Цвет его зеленый, если материал вводится:

private void txtLastname_TextChanged(object sender, EventArgs e) 
{ 
    //Lastname mandatory. 
    //Color pinkish if nothing entered. Greenish if entered. 
    if (txtLastname.Text.Trim() == "") 
    { 
     //Lastname is required, color pinkish 
     txtLastname.BackColor = ControlBad; 
    } 
    else 
    { 
     //Lastname entered, remove the coloring 
     txtLastname.BackColor = ControlGood; 
    } 
} 

Пример 2: первое имя не является обязательным, но попробовать, чтобы получить его. Мы добавим синеватый оттенок к этому «пытаются получить» поле:

private void txtFirstname_TextChanged(object sender, EventArgs e) 
{ 
    //Firstname can be blank. 
    //Hint them that they should *try* to get it with a bluish color. 
    //If they do enter stuff: it better be not all spaces. 
    if (txtFirstname.Text == "") 
    { 
     //Nothing there, hint it blue 
     txtFirstname.BackColor = ControlRequired; 
    } 
    else if (txtFirstname.Text.Trim() == "") 
    { 
     //They entered spaces - bad user! 
     txtFirstname.BackColor = ControlBad; 
    } 
    else 
    { 
     //Entered stuff, remove coloring 
     txtFirstname.BackColor = SystemColors.Window; 
    } 
} 

Пример 3возраст совершенно необязательно. Если возраст является введен, то лучше быть действительным:

private void txtAge_TextChanged(object sender, EventArgs e) 
{ 
    //Age is optional, but if entered it better be valid 
    int nAge = 0; 
    if (Int32.TryParse(txtAge.Text, out nAge)) 
    { 
     //Valid integer entered 
     if (nAge < 0) 
     { 
     //Negative age? i don't think so 
     txtAge.BackColor = ControlBad; 
     } 
     else 
     { 
     //Valid age entered, remove coloring 
     txtAge.BackColor = SystemColors.Window; 
     } 
    } 
    else 
    { 
     //Whatever is in there: it's *not* a valid integer, 
     if (txtAge.Text == "") 
     { 
     //Blank is okay 
     txtAge.BackColor = SystemColors.Window; 
     } 
     else 
     { 
     //Not a valid age, bad user 
     txtAge.BackColor = ControlBad; 
     } 
    } 
} 

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

Модель - это ваши данные.

В представлении показаны данные на экране.

Контроллер используется для выполнения пользователей действия

И апельсины вкуса оранжево.


Вот моя попытка разбить вещи, чтобы сделать код более трудным для подражания. Это где-то близко к MVC?

private void txtFirstname_TextChanged(object sender, EventArgs e) 
{ 
    FirstnameTextChangedHandler(sender, e); 
} 

private void FirstnameTextChangedHandler(sender, e) 
{ 
    string firstname = GetFirstname(); 

    Color firstnameTextBoxColor = GetFirstnameTextBoxColor(firstname); 

    SetFirstNameTextBoxColor(firstnameTextBoxColor); 
} 

private string GetFirstname() 
{ 
    return txtFirstname.Text; 
} 

private Color GetFirstnameTextBoxColor(string firstname) 
{ 
    //Firstname can be blank. 
    //Hint them that they should *try* to get it with a bluish color. 
    //If they do enter stuff: it better be not all spaces. 
    if (firstname == "") 
    { 
     //Nothing there, hint it blue 
     return GetControlRequiredColor(); 
    } 
    else if (firstname.Trim() == "") 
    { 
     //They entered spaces - bad user! 
     return GetControlBadColor(); 
    } 
    else 
    { 
     //Entered stuff, remove coloring 
     return GetControlDefaultColor(); 
    } 
} 

private Color GetControlRequiredColor() 
{ 
    return ControlRequired; 
} 

private Color GetControlBadColor() 
{ 
    return ControlBad; 
} 

private Color GetControlGoodColor() 
{ 
    return ControlGood; 
} 
//am i doin it rite 

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

Это следующий шаг, который я не понимаю. Какое логическое разделение функций перемещается в другие классы?Может ли кто-то перевести мои 3 простых примера выше в полноценную обфускацию MVC?


Редактировать: не ASP/ASP.NET/Online. Притворись, что это на рабочем столе, карманном компьютере, поверхности, киоске. И притворись, что это язык агностик.

+2

Вы принимаете издеваться? –

+0

Я не уверен, что это значит. Это британский сленг? –

+0

«Как довести до моего кода»; Разделение проблем и использование шаблонов там, где это необходимо, называют «хорошим» кодом, а не корпоративным кодом. – jfar

ответ

0

Большинство из того, что вы делаете в своем коде, принадлежит классу Контроллер, так как он описывает логику. Ваш View должен просто описать интерфейс и обеспечить легкий доступ к компонентам пользовательского интерфейса. Класс класс должен описывать вашу модель данных.

Идея проста: контроллер делает все, но он должен знать о View и модели. Например, как Просмотр инициализирован, Контроллер устанавливает всю логику (как то, что вы уже делаете). Как Модель назначена контроллеру - он устанавливает значения в соответствующие элементы пользовательского интерфейса и делает то же самое, что и для получения данных, а возврат - как . Модель.

Итак, в основном вы предоставляете свой класс модели данных контроллеру, он редактирует и возвращает ваши данные в качестве класса модели снова.

+0

В чем разница между «контроллером» или «презентатором», создающим событие изменения из текстового поля и WinForms? WinForms обрабатывает презентацию, они просто отправляют мне события, которые затем я могу использовать для управления представлением. Разве это не форма, а я - контролер? –

0

Было бы очень сложно следить за MVC в классическом ASP.NET, если это возможно, поэтому я отвечу на основе MVP.

В вашем первом примере вы пытаетесь сделать валидацию. Подтверждение фамилии несет Главный докладчик. Отображение поля красное - это представление View. Таким образом, ваш взгляд класс будет выглядеть так:

private void Page_Load() 
{ 
    this._presenter = new Presenter(); 
} 

private void txtLastname_TextChanged(object sender, EventArgs e) 
{ 
    txtLastName.BackColor = presenter.IsLastnameValid(txtLastName.Text) ? 
     ControlGood : ControlBad; 
} 

И ваш класс ведущий будет что-то вроде этого:

public Presenter() 
{ 
    public bool IsLastNameValid(string lastname) 
    { 
     return string.IsNullOrEmpty(lastname); 
    } 
} 

Фамилия ваша модель здесь.

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

+0

Можете ли вы рассказать о том, какие еще могут быть способы проверки? Кроме того, когда вы говорите «этот подход», вы имеете в виду мой подход, ваш подход, другие «лучшие» подходы? Наконец, что вы имеете в виду, когда говорите, что «этот» подход был бы лучше для вашего бизнеса, чем проверка? Это плохое утверждение? Является ли проверка достоверной? –

1

Основная идея, которую я имею при реализации MVC для Windows Forms, заключается в том, что я хочу иметь модульные тесты для моей модели и моего контроллера. Чтобы достичь этого, мой контроллер не должен знать ничего о его представлениях, поэтому любые уведомления, которые должны обрабатываться на уровне пользовательского интерфейса, реализуются как события. В вашем примере, мой контроллер будет выглядеть примерно так:

class Controller 
{ 
    // This is the model we are operating on 
    private Model model_; 

    public enum Status 
    { 
     Normal, 
     Required, 
     Good, 
     Bad 
    } 

    public delegate void FirstNameStatusChangedDelegate(Status newStatus); 
    public event FirstNameStatusChangedDelegate FirstNameStatusChangedEvent; 

    public string FirstName 
    { 
     get { return model_.FirstName; } 
     set 
     { 
      if (value == "") 
       RaiseFirstNameStatusChanged(Status.Required); 
      else if (value.Trim() == "") 
       RaiseFirstNameStatusChanged(Status.Bad); 
      else 
      { 
       model_.FirstName = value; 
       RaiseFirstNameStatusChanged(Status.Normal); 
      } 
     } 
    } 

    private void RaiseFirstNameStatusChanged(Status newStatus) 
    { 
     if (FirstNameStatusChangedEvent != null) 
      FirstNameStatusChangedEvent(newStatus); 
    } 
} 

И вид обеспечит обработчик для FirstNameStatusChanged события:

class View : Form 
{ 
    private Controller controller_; 
    private static readonly Dictionary<Controller.Status, Color> statusColors_ = new Dictionary<Controller.Status, Color> 
    { 
     {Controller.Status.Normal, SystemColors.Window}, 
     {Controller.Status.Required, ControlRequired}, 
     {Controller.Status.Good, ControlGood}, 
     {Controller.Status.Bad, ControlRed} 
    }; 

    public View(Controller controller) 
    { 
     InitializeComponent(); 
     controller_ = controller; 

     contoller_.FirstNameStatusChangedEvent += OnFirstNameStatusChanged; 
    } 

    private void txtFirstname_TextChanged(object sender, EventArgs e) 
    { controller_.FirstName = txtFirstName.Text; } 

    private void OnFirstNameStatusChanged(Controller.Status newStatus) 
    { txtFirstName.BackColor = statusColors_[newStatus]; } 
} 
+0

Вы ответили, что я просил, но человек заставляет мои глаза оглядываться. –

+0

Этот подход сильно отличается от обычного «бросить все внутри формы», но я считаю, что код, реализованный в соответствии с MVC, намного читабельнее и намного легче понять, не говоря уже о проверке и проверке. –

2

Цель паттернов MVC/MVP не запутывание, но separation of concerns , Обфускация составляет (conceal the) intended meaning in communication, making communication confusing, intentionally ambiguous, and more difficult to interpret: ref. Использование шаблонов - сделать код чистым и более понятным. Я предлагаю вам начать читать записи в Википедии на MVC и MVP.

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

+0

Я читал записи в Википедии. Купил книгу GoF, книгу о шаблонах дизайна на C#, прочитал оригинальные статьи на MVC в smalltalk и прочитал многочисленные веб-статьи и блоги. –

+0

Если вы уже сделали все это, то вам нужно что-то сделать вместе с ним, сделать некоторую кодировку. Честно говоря, похоже, вы передумали. –

+0

@Robery Harvey: Каждый раз, когда я начинаю, я нахожусь в замешательстве на Шаге №1: создаю модель, или вид, или контроллер.Мне нужны практические примеры. –

0

Ян,

Если вы хотите управления немедленно подтвердить, что вам нужно использовать Javascript или JQuery. Это справедливо и для классического ASP.NET. Поскольку вы используете методы Code Behind, я предполагаю, что ваша проверка ожидает обратной передачи.

Следующие примеры из проекта NerdDinner. NerdDinner - проект с открытым исходным кодом, который служит примером архитектуры ASP.NET MVC. Авторы любезно предоставил учебник с ним, доступный на http://nerddinnerbook.s3.amazonaws.com/Intro.htm

Когда форма представлена ​​в ASP.NET MVC, она входит в соответствующий контроллер в качестве объекта FormCollection:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Edit(int id, FormCollection formValues) { 
    Dinner dinner = dinnerRepository.GetDinner(id); 

    try 
    { 
     UpdateModel(dinner); 
     dinnerRepository.Save(); 
    } 
    catch 
    { 
     ModelState.AddModelErrors(dinner.GetRuleViolations()) 
    } 
    return RedirectToAction("Details", new { id = dinner.DinnerID }); 
} 

UpdateModel принимает значения формы и пытается набить их в предмет обеда. Объект ужина выглядит так:

public partial class Dinner { 
    public bool IsValid { 
     get { return (GetRuleViolations().Count() == 0); } 
    } 
     public IEnumerable<RuleViolation> GetRuleViolations() { 
     yield break; 
    } 
    public IEnumerable<RuleViolation> GetRuleViolations() { 

     if (String.IsNullOrEmpty(Title)) 
      yield return new RuleViolation("Title is required", "Title"); 

     if (String.IsNullOrEmpty(Description)) 
      yield return new RuleViolation("Description is required", "Description"); 

     if (String.IsNullOrEmpty(HostedBy)) 
      yield return new RuleViolation("HostedBy is required", "HostedBy"); 

     if (String.IsNullOrEmpty(Address)) 
      yield return new RuleViolation("Address is required", "Address"); 

     if (String.IsNullOrEmpty(Country)) 
      yield return new RuleViolation("Country is required", "Address"); 

     if (String.IsNullOrEmpty(ContactPhone)) 
      yield return new RuleViolation("Phone# is required", "ContactPhone"); 

     if (!PhoneValidator.IsValidNumber(ContactPhone, Country)) 
      yield return new RuleViolation("Phone# does not match country", "ContactPhone"); 

     yield break; 
    } 
    partial void OnValidate(ChangeAction action) { 
     if (!IsValid) 
      throw new ApplicationException("Rule violations prevent saving"); 
    } 
} 

Обратите внимание на метод IsValid и перечислитель RuleViolations. Если все настроено правильно, все, что вам нужно сделать, это определить свои валидации здесь, и ASP.NET MVC позаботится обо всем остальном.

Окончательный результат подтверждено выглядит следующим образом:

alt text

Я призываю вас, чтобы получить приложение NerdDinner и учебник по http://nerddinner.codeplex.com/

+0

Я не пользуюсь Интернетом. Притворись, что это язык агностического компьютерного кода. –

Смежные вопросы