Обобщенный Model-View-Controller
От: Сергей Рогачев Россия http://rsn81.wordpress.com
Дата: 23.03.07 04:21
Оценка: 231 (15) +1 -2
Статья:
Обобщенный Model-View-Controller
Автор(ы): Сергей Рогачев
Дата: 23.03.2007
В статье рассматривается вариант реализации шаблона проектирования Model-View-Controller в виде каркаса приложения на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command и показаны варианты их применения в рассматриваемой реализации Model-View-Controller. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.


Авторы:
Сергей Рогачев

Аннотация:
В статье рассматривается реализация шаблона проектирования Model-View-Controller на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.
Re: Обобщенный Model-View-Controller
От: Al_Shargorodsky Украина  
Дата: 23.03.07 07:16
Оценка: 5 (1)
Здравствуйте, Сергей Рогачев, Вы писали:

Возможно, кого-то заинтересует, как архитектура может выглядеть при использовании WPF. Если коротко — контроллер оказывается не нужным в принципе...
Re[2]: Обобщенный Model-View-Controller
От: IB Австрия http://rsdn.ru
Дата: 23.03.07 08:50
Оценка: 5 (1)
Здравствуйте, Al_Shargorodsky, Вы писали:

A_S> Если коротко — контроллер оказывается не нужным в принципе...

Да, там его переименовали в ViewModel... =) Когда контроллер не реализуется в принципе — это паттерн DocumentView. Там логика контроллера реализуется во View, что затрудняет тестирование и обладает рядом других недостатков...

http://rsdn.ru/?article/patterns/ModelViewPresenter.xml
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re: Обобщенный Model-View-Controller
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 23.03.07 10:58
Оценка: 12 (1)
Здравствуйте, Сергей Рогачев, Вы писали:

СР>Статья:

СР>Обобщенный Model-View-Controller
Автор(ы): Сергей Рогачев
Дата: 23.03.2007
В статье рассматривается вариант реализации шаблона проектирования Model-View-Controller в виде каркаса приложения на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command и показаны варианты их применения в рассматриваемой реализации Model-View-Controller. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.


СР>пара комментариев:


1.

...отсутствует четкое разделение между представлением и контроллером, в особенности это касается .NET...

Ну как сказать, Swing вообще работает только с model + UI, где UI = view + controller;

2. Отсутствуют проверки на null принимаемых аргументов и не решена упоминавшаяся проблема с синхронизацией. Причем не только синхронизированный listeners management, но и синхронизированные доступы к свойству
Пример:

public abstract class Model<P> {

    private P property;

    ...

    public Model(P property) {
        this.property = property;
    }

    public P getProperty() {
        return property;
    }

    public void setProperty(P property) {
        this.property = property;
        notifyListeners();
    }
...

Если get() происходит после того, как начался set(), но до того, как он закончился, будут проблемы;

3. finalize() использовать настоятельно не рекомендуется. Почему можно почитать у того же Brian Goetz. Вместо этого используется механизм фантомных ссылок;

4. Для работы с listeners также лучше применять слабые ссылки с целью избежания утечки памяти. Подробнее здесь;

5. Имхо не самая оптимальная работа с дженериками. Я по-быстрому перекидал их:

Model.java
package ru.rsdn.mvc.model;

import java.util.Collection;
import java.util.HashSet;

public abstract class Model<P> {

    private P property;

    private final Collection<IModelSubscriber<P>> subscribers = new HashSet<IModelSubscriber<P>>();

    public Model(P property) {
        this.property = property;
    }

    public P getProperty() {
        return property;
    }

    public void setProperty(P property) {
        this.property = property;
        notifyListeners();
    }

    protected void notifyListeners() {
        for (IModelSubscriber<P> listener : subscribers) {
            notifyListener(listener);
        }
    }

    private void notifyListener(IModelSubscriber<P> subscriber) {
        subscriber.modelChanged(this);
    }

    public void subscribe(IModelSubscriber<P> subscriber) {
        assert !subscribers.contains(subscriber) : "Повторная подписка: "
                + subscriber;
        subscribers.add(subscriber);
        notifyListener(subscriber);
    }

    public void unsubscribe(IModelSubscriber subscriber) {
        assert subscribers.contains(subscriber) : "Неизвестный подписчик: "
                + subscriber;
        subscribers.remove(subscriber);
    }

    public String toString() {
        return property.toString();
    }
}


IModelSubscriber.java
package ru.rsdn.mvc.model;

public interface IModelSubscriber<P> {

    void modelChanged(Model<P> model);
}


ListModel.java
package ru.rsdn.mvc.model;

import java.util.Collection;
import java.util.HashSet;

public class ListModel<P> extends Model<Collection<Model<P>>> implements IModelSubscriber<P> {

    public ListModel() {
        super(new HashSet<Model<P>>());
    }
    
    public void add(Model<P> model) {
        getProperty().add(model);
        model.subscribe(this);
    }


    public void modelChanged(Model<P> model) {
        notifyListeners();
    }

    public void remove(Model<P> model) {
        model.unsubscribe(this);
        getProperty().remove(model);
        notifyListeners();
    }
}


Controller.java
package ru.rsdn.mvc.controller;

import ru.rsdn.mvc.model.Model;

public class Controller<P> implements IController<Controller.Operations, P, Model<P>> {
    
    public enum Operations {EDIT}

    public void execute(Operations operation, Model<P> model, P attribute) {
        assert attribute != null : "Не передан атрибут в операцию";
        switch (operation) {
        case EDIT:
            model.setProperty(attribute);
            break;
        default:
            assert false : "Неизвестная операция: " + operation;
        }
    }
}


IController.java
package ru.rsdn.mvc.controller;

import ru.rsdn.mvc.model.Model;

public interface IController<O, P, M extends Model<P>> {

    void execute(O operation, M model, P attribute);
}


ListController.java
package ru.rsdn.mvc.controller;

import ru.rsdn.mvc.model.ListModel;
import ru.rsdn.mvc.model.Model;

import java.util.Collection;
import java.util.Arrays;

public class ListController<P> implements IController<ListController.Operations, Collection<Model<P>>, ListModel<P>> {

    public enum Operations {ADD, REMOVE}

    public void execute(Operations operation, ListModel<P> listModel, Model<P> attribute) {
        execute(operation, listModel, Arrays.asList(attribute));
    }

    public void execute(Operations operation, ListModel<P> listModel, Collection<Model<P>> attribute) {
        assert attribute != null : "Не передан атрибут в операцию";
        switch (operation) {
            case ADD:
                for (Model<P> model : attribute) {
                    listModel.add(model);
                }
                break;
            case REMOVE:
                for (Model<P> model : attribute) {
                    listModel.remove(model);
                }
                break;
            default:
                assert false : "Неизвестная операция: " + operation;
        }
    }
}


BaseView.java
package ru.rsdn.mvc.view;

import ru.rsdn.mvc.model.IModelSubscriber;
import ru.rsdn.mvc.model.Model;

public abstract class BaseView<P, M extends Model<P>> implements IModelSubscriber<P> {
    private M model;

    protected M getModel() {
        return model;
    }

    public void setModel(M model) {
        unsubscribe();
        this.model = model;
        subscribe();
    }

    private void subscribe() {
        if (model != null) {
            model.subscribe(this);
        }
    }

    private void unsubscribe() {
        if (model != null) {
            model.unsubscribe(this);
        }
    }

    protected void finalize() throws Throwable {
        unsubscribe();
        super.finalize();
    }
}


View.java
package ru.rsdn.mvc.view;

import ru.rsdn.mvc.controller.Controller;
import ru.rsdn.mvc.model.Model;

public abstract class View<P> extends BaseView<P, Model<P>> {

    private final Controller<P> controller = new Controller<P>();

    protected void edit(P property) {
        controller.execute(Controller.Operations.EDIT, getModel(), property);
    }
}


ListView.java
package ru.rsdn.mvc.view;

import ru.rsdn.mvc.controller.Controller;
import ru.rsdn.mvc.controller.ListController;
import ru.rsdn.mvc.model.ListModel;
import ru.rsdn.mvc.model.Model;

import java.util.Collection;

public abstract class ListView<P> extends BaseView<Collection<Model<P>>, ListModel<P>> {

    private final Controller<P> controller = new Controller<P>();
    private final ListController<P> listController = new ListController<P>();

    protected void edit(Model<P> model, P property) {
        controller.execute(Controller.Operations.EDIT, model, property);
    }

    protected void add(Model<P> model) {
        listController.execute(ListController.Operations.ADD, getModel(), model);
    }

    protected void delete(Model<P> model) {
        listController.execute(ListController.Operations.REMOVE, getModel(), model);
    }
}


6. В текущей реализации для выбора нужной операции используется switch. В перспективе это не самое удобное решение (например, будет не две операции, а двадцать две). Лучше сделать через набор обработчиков операций, имеющих общий интерфейс (пока в джаве нет делегатов) и при необходимости обработать команду, брать из map нужный обработчик и делегировать задачу ему;
http://denis-zhdanov.blogspot.com
Re[2]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 24.03.07 12:24
Оценка:
Здравствуйте, bolshik, Вы писали:

1. Приводил в свое время пример Swing MVC здесь: Re[8]: вопрос по паттерну MVC
Автор: rsn81
Дата: 19.09.06
, что и было прокомментировано в статье:

контроллер представляет собой набор анонимных классов обработки соответствующих событий


2-5. Ага, так и есть — не хотелось усложнять примеры:

Приводимый код вовсе не является готовым решением. Для наглядности указания направления, в котором, возможно, стоит двигаться, компоненты реального приложения были максимально упрощены, а демонстрационные примеры программ приведены для подтверждения верности выбранного решения.


2. Установить в классе Model cинхронизацию по property в методе setProperty, но, по-моему, смысла в этом мало.
3. Да. Но в данном случае это не страшно: методы finalize используются в классах представлений, которые создаются-собираются не так часто.
4. Спасибо, надо изучить на досуге.
5. Супер, большое спасибо за рефакторинг! Именно так и пытался сделать вначале, но камнем преткновения становился ListController (и ListView), в котором вы предложили такой "финт ушами" сделать, до которого сам не смог додуматься.

Обновил исходный код: http://rsdn.ru/File/57445/mvc-rsdn_1.5-java-src.zip
Изменения в версии 1.5:
1. Изменена работа с generic-ами по варианту bolshik-а.
2. Список подписчиков модели в классе Model<P> на основе класса CopyOnWriteArrayList (ранее на HashSet), по рекомендации Браяна Гетца http://www.ibm.com/developerworks/ru/library/j-jtp07265/index.html

PS Статье на самом деле уже больше полугода — Java-код статьи выдирался из рабочих проектов в августе-сентябре 2006 года. Код серьезно уже давно не смотрел, т.к., в принципе, по работе уже отошел от MVC: после статьи IB Model-View-Controller в .Net
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
, а конкретно про модификацию MVC — Model-View-Presenter — успешно переполз на него и радуюсь пассивной модели.
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[3]: Обобщенный Model-View-Controller
От: Al_Shargorodsky Украина  
Дата: 26.03.07 05:56
Оценка:
Здравствуйте, IB, Вы писали:

IB>Да, там его переименовали в ViewModel... =) Когда контроллер не реализуется в принципе — это паттерн DocumentView. Там логика контроллера реализуется во View, что затрудняет тестирование и обладает рядом других недостатков...


Всетаки ViewModel это не совсем контроллер-презентер. Я бы сказал так — ViewModel можно привести к виду презентера, но это только частный случай. Модифицируем тот же пример
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
.
   public class Model : INotifyPropertyChanged
   {
      private double _valueFahrenheit = 32;
      private double _valueCelsius = 0;

      public event PropertyChangedEventHandler PropertyChanged;

      public double valueFahrenheit
      {
         get { return _valueFahrenheit; }
         set 
            { 
            _valueFahrenheit = value;
            _valueCelsius = (_valueFahrenheit - 32) * 5 / 9;
            NotifyPropertyChanged("valueFahrenheit");
         }
      }

      public double valueCelsius
      {
         get { return _valueCelsius; }
         set 
         { 
            _valueCelsius = value;
            _valueFahrenheit = _valueCelsius * 9 / 5 + 32;
            NotifyPropertyChanged("valueCelsius");
         }
      }

      private void NotifyPropertyChanged(String info)
      {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
      }
   }

где-то в XAML
<DataTemplate DataType=src:Model>
  <TextBlock Text={Binding valueFahrenheit}/>
  ... и так далее
</DataTemplate>


Больше не нужно ничего — всю черновую работу сделает фреймворк. Класс Model здесь — это и ViewModel и DataModel одновременно. Пример, конечно примитивный, но думаю, суть понятна.
Re[3]: Обобщенный Model-View-Controller
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 26.03.07 06:46
Оценка:
Здравствуйте, rsn81, Вы писали:

R>...


R>2. Установить в классе Model cинхронизацию по property в методе setProperty, но, по-моему, смысла в этом мало.


Не, смысл-то есть, единственно что эффективнее будет работать не через старые примитивы синхронизации (использование synchronized), а через AtomicReference. Почему это эффективнее, и вообще о CAS-инструкциях можно почитать у того же Brian Goetz


R>3. Да. Но в данном случае это не страшно: методы finalize используются в классах представлений, которые создаются-собираются не так часто.


Спорить не буду, потому что тут, имхо, уже дело субъективное. Я бы либо не использовал finalize() в примере вообще, либо делал на фантомных ссылках, но хозяин барин


R>5. Супер, большое спасибо за рефакторинг! Именно так и пытался сделать вначале, но камнем преткновения становился ListController (и ListView), в котором вы предложили такой "финт ушами" сделать, до которого сам не смог додуматься.


Welcome
http://denis-zhdanov.blogspot.com
Re[4]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 26.03.07 08:20
Оценка:
Здравствуйте, bolshik, Вы писали:

B>Не, смысл-то есть, единственно что эффективнее будет работать не через старые примитивы синхронизации (использование synchronized), а через AtomicReference. Почему это эффективнее, и вообще о CAS-инструкциях можно почитать у того же Brian Goetz

Да, эту статью про неблокирующие алгоритмы CAS уже читал. Вопрос только в том, действительно ли в приложении будет несколько потоков, борющихся за доступ к модели — может чего-то путаю, но вроде SWT и Swing исполняются в одном потоке.
Re[4]: Обобщенный Model-View-Controller
От: IB Австрия http://rsdn.ru
Дата: 26.03.07 08:33
Оценка:
Здравствуйте, Al_Shargorodsky, Вы писали:

A_S>Всетаки ViewModel это не совсем контроллер-презентер.

Да, не совсем — это только часть контроллера.

A_S> Я бы сказал так — ViewModel можно привести к виду презентера, но это только частный случай.

Не совсем так.
В MVP Presenter (контроллер) выполняет, с одной стороны роль медиатора для модели, а с другой управляет набором View.
В случае WPF ребята эти две роли разделили, в результате Presenter распался на две части: DataModel — медиатор между моделью и View, ModelView — управляет View. Модель же и View остались неизменными. Таким образом, паттерн распался на 4 компонента — Model, DataModel, ModelView и View.
Они сами об этом и пишут: "DataModel is responsible for exposing data in a way that is easily consumable by WPF. All of its public APIs must be called on the UI thread only" Иными словами, роль DataModel в том, чтобы представить данные(Model) в том виде, в котором они удобны для WPF, то есть классическое применение паттерна медиатор.
Касательно ViewModel — "A ViewModel is a model for a view in the application (duh!). It exposes data relevant to the view and exposes the behaviors for the views, usually with Commands"

A_S> public class Model : INotifyPropertyChanged

Если Model — это по прежнему модель, то так делать нельзя. Модель по определению ничего не знает о контроллере и его интерфейсах, а INotifyPropertyChanged — это именно интерфейс контроллера, точнее медиатора для View, а не модели. А у одной модели может быть несколько Презентеров.

A_S> Класс Model здесь — это и ViewModel и DataModel одновременно.

Тогда Model переходит в разряд презентеров.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re[5]: Обобщенный Model-View-Controller
От: bolshik Россия http://denis-zhdanov.blogspot.com/
Дата: 26.03.07 09:00
Оценка: +1
Здравствуйте, rsn81, Вы писали:

R>Да, эту статью про неблокирующие алгоритмы CAS уже читал. Вопрос только в том, действительно ли в приложении будет несколько потоков, борющихся за доступ к модели — может чего-то путаю, но вроде SWT и Swing исполняются в одном потоке.


Насчет SWT не знаю, но Swing да, работает в одном потоке, но в то же время никто не запрещает вызвать сеттер модели из другого потока, не EDT. При этом с одной стороны виноват программист, который вызывает его не из EDT, а с другой стороны удобнее использовать класс, просто вызывая сеттер, чем постя обновление через invokeLater(). Т.к. издержки на производительность при этом незначительные (из-за поддержки CAS-инструкций процессором), кажется, что оно того стоит.
http://denis-zhdanov.blogspot.com
Re[6]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 26.03.07 16:08
Оценка:
Здравствуйте, bolshik, Вы писали:

Статья обновлена до версии 2.5 с учетом ваших замечаний, еще раз спасибо.
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[3]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 26.03.07 17:10
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Model-View-Presenter — успешно переполз на него и радуюсь пассивной модели.

Если интересно, то вот демонстрационный пример Generic MVP — все интересное, что описано в разделе статьи "Внедрение", перенесено и в MVP: Undo/Redo (полная поддержка) и клонирование.
... << RSDN@Home 1.2.0 alpha rev. 676>>
Re[5]: Обобщенный Model-View-Controller
От: Al_Shargorodsky Украина  
Дата: 29.03.07 05:07
Оценка:
Здравствуйте, IB, Вы писали:

Пару дней пересматривал архитектуру своего текущего проекта и собственные представления в этой области. Пока остался при своем мнении... Буду признателен за дальнейшие разъяснения

A_S>> public class Model : INotifyPropertyChanged

IB>Если Model — это по прежнему модель, то так делать нельзя. Модель по определению ничего не знает о контроллере и его интерфейсах, а INotifyPropertyChanged — это именно интерфейс контроллера, точнее медиатора для View, а не модели. А у одной модели может быть несколько Презентеров.
Т.е. чтобы использовать binding в обе стороны, нужно будет делать либо обертку вокруг модели, либо делать свойства модели виртуальными и плодить наследников? Но что мешает сделать несколько DataTemplate и получить несколько Представлений, при этом еще и синхронизированных?

A_S>> Класс Model здесь — это и ViewModel и DataModel одновременно.

IB>Тогда Model переходит в разряд презентеров.
Собственно, я и пытаюсь сказать, что разделение на Модель и Презентер в WPF становится не актуальным — данные уже отделены от Представления средствами фреймворка, а логика реализуется либо во ViewModel, либо в классах-обработчиках команд, либо вообще в отдельных блоках, подписанных на тот же PropertyChanged соответствующего объекта.
Re[6]: Обобщенный Model-View-Controller
От: IB Австрия http://rsdn.ru
Дата: 29.03.07 09:29
Оценка: 5 (2)
Здравствуйте, Al_Shargorodsky, Вы писали:

A_S>Т.е. чтобы использовать binding в обе стороны, нужно будет делать либо обертку вокруг модели, либо делать свойства модели виртуальными и плодить наследников?

Не либо. Обертка во круг модели, других вариантов нет.

A_S> Но что мешает сделать несколько DataTemplate и получить несколько Представлений, при этом еще и синхронизированных?

Тем, что это прибъет модель гвоздями к WPF.

A_S>Собственно, я и пытаюсь сказать, что разделение на Модель и Презентер в WPF становится не актуальным — данные уже отделены от Представления средствами фреймворка, а логика реализуется либо во ViewModel, либо в классах-обработчиках команд, либо вообще в отдельных блоках, подписанных на тот же PropertyChanged соответствующего объекта.

Понимаешь, модель может быть представима не только в WPF. Например в моих задачах одну и ту же модель нужно пихать в веб-сервисы, отображать на вебе и WinForms, помимо самого WPF, и еще чего-нибудь хитрое с ней делать. И это скорее правило, нежели исключение.
Поэтому делать из модели WPF-овский презентер — не лучшая идея.
... << RSDN@Home 1.2.0 alpha rev. 673>>
Мы уже победили, просто это еще не так заметно...
Re: Обобщенный Model-View-Controller
От: Аноним  
Дата: 29.03.07 10:34
Оценка:
Как посмотреть код исходников для ASP.NET?
Re[2]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 29.03.07 10:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Как посмотреть код исходников для ASP.NET?

http://rsdn.ru/article/patterns/generic-mvc.xml#EDBBG
Автор(ы): Сергей Рогачев
Дата: 23.03.2007
В статье рассматривается вариант реализации шаблона проектирования Model-View-Controller в виде каркаса приложения на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command и показаны варианты их применения в рассматриваемой реализации Model-View-Controller. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.
Re: Обобщенный Model-View-Controller
От: Дмитрий В  
Дата: 29.03.07 14:45
Оценка: 4 (1)
Здравствуйте, Сергей Рогачев, Вы писали:

СР>Статья:

СР>Обобщенный Model-View-Controller
Автор(ы): Сергей Рогачев
Дата: 23.03.2007
В статье рассматривается вариант реализации шаблона проектирования Model-View-Controller в виде каркаса приложения на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command и показаны варианты их применения в рассматриваемой реализации Model-View-Controller. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.


СР>Авторы:

СР> Сергей Рогачев

СР>Аннотация:

СР>В статье рассматривается реализация шаблона проектирования Model-View-Controller на основе обобщенного программирования языков Java и C#. В описании предлагаемого решения, кроме того, будут рассмотрены шаблоны проектирования Mediator, Observer и Command. Предполагается наличие у читателя знания базовых шаблонов проектирования, языка UML, диаграммами которого будут сопровождаться описания, а также одного из указанных языков программирования.

Честно говоря тема реализации грамотного гуевого фреймворка не раскрыта.
Нуда, есть MVC и все такое, слушатели, подписчики — об этом и так много книг написано.
Только делать слабые связи между обьектами нужно не потому, что об этом написано везде в книжках и что это хорошо, а потому, что это действительно надо.
И с самого начала статьи надо было написать — есть такая то проблема, и она решается так то так. А статья начинается с того, что "В статье рассматривается реализация шаблона проектирования Model-View-Controller" — вот она оказывается какая проблема — хотим MVC использовать, потому что это хорошо.. нде...
Re[7]: Обобщенный Model-View-Controller
От: Al_Shargorodsky Украина  
Дата: 29.03.07 15:18
Оценка:
Здравствуйте, IB, Вы писали:

IB>Понимаешь, модель может быть представима не только в WPF. Например в моих задачах одну и ту же модель нужно пихать в веб-сервисы, отображать на вебе и WinForms, помимо самого WPF, и еще чего-нибудь хитрое с ней делать. И это скорее правило, нежели исключение.

IB>Поэтому делать из модели WPF-овский презентер — не лучшая идея.

Спасибо, вобщем я где-то так и думал. И все-таки — настолько ли сильно реализация INotifyPropertyChanged привязывает к определенному Представлению? Это ведь просто событие — не хочешь, не подписывайся...
Re[2]: Обобщенный Model-View-Controller
От: Дмитрий В  
Дата: 29.03.07 17:06
Оценка:
В том же Swing'e жавовском MVC в каждом визуальном компоненте — даже у кнопки есть ButtonModel (не говоря уже о таблице), есть контроллер (сам обьект кнопки JButton) и view — ButtonUI. И там как раз JButton подписывается на события изменения модели и вся остальная приблуда тоже присутствует.
Re[2]: Обобщенный Model-View-Controller
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 29.03.07 17:43
Оценка: 9 (3)
Здравствуйте, Дмитрий В, Вы писали:

Во-первых, эта "нераскрытость" несколько другой тематики, например, что-то вроде Признаки плохого кода
Автор(ы): Джошуа Кериевски
Дата: 31.10.2006
Глава из книги "Рефакторинг с использованием шаблонов".
Наиболее распространенные проблемы проектов возникают в следующих случаях:
— если код содержит повторы;
— если он непонятен;
— если он сложен.
Эти критерии определенно могут помочь обнаружить в коде места, нуждающиеся в улучшении. С другой стороны, многие программисты считают этот список слишком неопределенным: не понятно, как опознать в коде повторения, если они не совсем одинаковы; невозможно с полной уверенностью судить, ясно ли говорит код о своем назначении, не понятно, как отличить простой код от сложного.
, Почему ваш код &mdash; отстой
Автор(ы): Дейв Эстелс (Dave Astels)
Дата: 13.06.2006
Если Вы программируете как большинство, и даже, вероятно, все программисты (скромненько включая автора этой статьи), то ваш код – отстой. Возможно, не целиком; возможно, не всегда, но наверняка какая-то его часть и в какой-то момент времени.
и т.п. — мне нравится в этом отношении статья О потерянном уровне. В обсуждаемой же статье, как и обычно, приведены шаблоны как решения типовых задач, то есть четко сказано, где они применяются и какой выигрыш дают. Мне кажется излишним приводить листинг "бездумного" кода, это, как понимаете, в отличие от шаблонов слишком многовариантно, хотя в книге по первой ссылке это и попытались сделать.

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

В подтверждение последнего анекдот собственной жизни. В свое время сразу после университета, в ту пору, когда каждый студент думает, что он знает и может все, опробовал на своем собственном лбу n-количество граблей, после чего нашел несколько, как мне тогда показалось, гениальных решений. И каким же было мое изумление, когда позже в период переосмысления своих завышенных в студенчестве возможностей, я узнал, что, оказывается, ничто не ново под Луной. Оказалось, что моим "гениальным решениям" (насколько помню, использовал тогда жуткие собственные интерпретации AbstractFactory, State, Decorator, Adapter, Command, Observer, Singleton, Mapper, Memento и что-то еще, все не упомнить... особенно то, как я сам их называл, хотя скорее всего просто интуитивно применял без формализации и классификации) сто лет в обед, называются они шаблонами проектирования, имеют "умные" названия и классификацию. Жутко тогда расстроился, а потом подумал, посмеялся... и понял, что именно такой путь и нужно проделать на пути проектирования: дойти своими мозгами хотя бы до постановки проблемы, четко ее сформулировать самому себе, а вот только после этого смотреть готовые решения этой проблемы.
... << RSDN@Home 1.2.0 alpha rev. 676>>
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.