Совместное использование модели в приложении MVP Winforms - PullRequest
5 голосов
/ 18 сентября 2009

Я работаю над созданием приложения MVP (C # Winforms). Моя начальная версия на Критика моего простого приложения MVP Winforms ... Теперь я увеличиваю сложность. Я разбил код для обработки двух отдельных текстовых полей на две пары вид / презентатор. Это тривиальный пример, но он должен проработать детали нескольких докладчиков, использующих одну и ту же модель.

Мои вопросы по поводу модели:

  1. Я в основном использую событие свойства, вызванное моделью, для уведомления представлений о том, что что-то изменилось. Это хороший подход? Что делать, если доходит до того, что у меня есть 100 или 1000 свойств? Это все еще практично в этот момент?

  2. Является ли создание экземпляра модели в каждом докладчике с NoteModel _model = NoteModel.Instance правильным подходом? Обратите внимание, что я хочу убедиться, что все докладчики используют одни и те же данные.

  3. Если есть лучший подход, я открыт для предложений ....

Мой код выглядит так:

NoteModel.cs

public class NoteModel : INotifyPropertyChanged
{
    private static NoteModel _instance = null;

    public static NoteModel Instance
    {
        get { return _instance; }
    }

    static NoteModel()
    {
        _instance = new NoteModel();
    }

    private NoteModel()
    {
        Initialize();
    }

    public string Filename { get; set; }
    public bool IsDirty { get; set; }
    public readonly string DefaultName = "Untitled.txt";

    string _sText;
    public string TheText
    {
        get { return _sText; }
        set
        {
            _sText = value;
            PropertyHasChanged("TheText");
        }
    }

    string _sMoreText;
    public string MoreText
    {
        get { return _sMoreText; }
        set
        {
            _sMoreText = value;
            PropertyHasChanged("MoreText");
        }
    }

    public void Initialize()
    {
        Filename = DefaultName;
        TheText = String.Empty;
        MoreText = String.Empty;
        IsDirty = false;
    }

    private void PropertyHasChanged(string sPropName)
    {
        IsDirty = true;

        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(sPropName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

TextEditorPresenter.cs

public class TextEditorPresenter
{
    ITextEditorView _view;
    NoteModel _model = NoteModel.Instance;

    public TextEditorPresenter(ITextEditorView view)//, NoteModel model)
    {
        //_model = model;
        _view = view;
        _model.PropertyChanged += new PropertyChangedEventHandler(model_PropertyChanged);
    }

    void model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == "TheText")
            _view.TheText = _model.TheText;
    }

    public void TextModified()
    {
        _model.TheText = _view.TheText;
    }

    public void ClearView()
    {
        _view.TheText = String.Empty;
    }
}

TextEditor2Presenter.cs по сути тот же, за исключением того, что он работает на _model.MoreText вместо _model.TheText.

ITextEditorView.cs

public interface ITextEditorView
{
    string TheText { get; set; }
}

ITextEditor2View.cs

public interface ITextEditor2View
{
    string MoreText { get; set; }
}

Ответы [ 3 ]

3 голосов
/ 18 сентября 2009
  1. Этот подход хорош. Однако, если вы смотрите на наличие сотен (даже тысяч!) Свойств, то я думаю, что у вас может быть класс Бога (анти-паттерн). Есть не так много хороших классов с 100 свойствами. Вместо этого рассмотрите возможность разделения вашей модели на более мелкие классы. Кроме того, вам не нужно иметь отдельное событие для каждого свойства. Если модель вообще изменяется, вы можете запустить одно событие (которое может включать информацию, описывающую изменение), и представления могут обработать его оттуда.
  2. Я бы не использовал шаблон Singleton, если вы не уверены, что хотите его применить. Вместо этого измените конструктор для всех ваших представлений на экземпляр модели.
1 голос
/ 14 апреля 2010
  • К вопросу 1. Внедрение INotifyPropertyChanged представляется мне хорошей идеей. Однако, вероятно, вы бы разбили многие свойства на несколько классов.
  • К Вопросу 2: В настоящее время я использую шаблон Singleton для предоставления своей модели MVP нескольким докладчикам Пока я счастлив, поскольку это гарантирует, что в моей модели действительно только один экземпляр.
1 голос
/ 30 сентября 2009

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

  1. Таким образом, я бы попросил вашего докладчика передать ваш экземпляр Note представлению (которое, без сомнения, является каким-то элементом управления), а затем разрешить привязку данных через BindingSource. Как только вы используете привязку данных, элементы управления автоматически прослушивают событие PropertyChanged и обновляются соответствующим образом без необходимости в дополнительном коде с вашей стороны. Уведомление на основе событий является подходящим использованием здесь, независимо от того, сколько свойств контролируется, поскольку только объекты, которые заботятся об изменении, будут действовать (вместо того, чтобы многие объекты выполняли действие без необходимости).

  2. Как правило, вы получаете экземпляры вашей сущности с нижнего уровня. Например, вы можете реализовать сервис, который возвращает ваши экземпляры Note. Каждый раз, когда вы запрашиваете этот сервис для Note # 3, он возвращает тот же экземпляр Note, который он создал из постоянных данных. Более того, вы можете добавить еще один элемент в свой бизнес-уровень для дополнения своих докладчиков - это может быть вызов WorkItem или Controller. Все ваши докладчики могут обратиться к своему экземпляру WorkItem, чтобы получить текущий экземпляр Note, над которым будет работать пользователь.

Я бы рассмотрел примеры того, как Блок составного приложения (или CAB ) использует эти шаблоны для создания интеллектуальных клиентских приложений. Это все шаблоны проектирования и принципы ОО, реализация которых стоит усилий.

...