Webforms MVP Passive View - обработка событий - PullRequest
6 голосов
/ 14 марта 2010

Должно ли представление не иметь ничего конкретного события в его интерфейсе и вызывать простые методы докладчика для обработки событий и не иметь никаких официальных EventHandlers? Например

// ASPX
protected void OnSaveButtonClicked(object sender, EventArgs e)
{
  _Presenter.OnSave();
}

Или в представлении должны быть определены события EventHandlers в его интерфейсе и они явно связаны с событиями на странице управления

// View
    public interface IView
    {
 ...
        event EventHandler Saved;
 ...
    }

// ASPX Page implementing the view
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        SaveButton.Click += delegate { Saved(this, e); };
    }

// Presenter
    internal Presenter(IView view,IRepository repository)
    {
       _view = view;
       _repository = repository;
       view.Saved += Save;
    }

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

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

Обновление: нуждается ли мой вопрос в дальнейшем уточнении?

Ответы [ 3 ]

6 голосов
/ 24 июня 2010

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

Элементы управления могут быть реализованы очень по-разному для разных типов проектов (например, Winforms и ASP).

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

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

1 голос
/ 13 мая 2010

Мы только что реализовали MVP с использованием веб-форм и выбрали более простой вариант - иметь методы вызова представления на презентаторе непосредственно для событий кнопок и т. Д.

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

По моему опыту, вы никогда не достигнете полностью чистого MVP в WebForms из-за природы зверя (они бы очень хотели, чтобы вы просто использовали этот код за файлом ...), так что я бы не стал не зацикливайся на этом.

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

0 голосов
/ 13 мая 2010

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

// View interface
public interface IView
{
    Button SaveButton;
}

// View code behind
public Button SaveButton
{
   get { return btnSave; }
}

//  Presenter
internal Presenter(IView view,IRepository repository)
{
   _view = view;
   _repository = repository;
   view.SaveButton.Click += new EventHandler(Saved);;
}

void Saved(object sender, EventArgs e)
{
   // do save
}

...