Re[12]: Где конструктив ?
От: shvonder Россия  
Дата: 22.11.07 15:24
Оценка:
Здравствуйте, rsn81, Вы писали:
Боясь быть назойливым, переспрашиваю:
Имеем модель неактивного Presenter'а, который ничего сам не делает, а только реализует интерфейс. Стоит ли для каждого диалога делать интерфейс, чтобы постредством него Presenter манипулировал ими наравне с остальными View'ами ?
Спасибо.
Re[13]: Где конструктив ?
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 22.11.07 15:40
Оценка:
Здравствуйте, shvonder, Вы писали:

S>Боясь быть назойливым, переспрашиваю:

[skipped]
Я так понимаю, вы следуете статье Model-View-Controller в .Net
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
? Если так, то ничего не посоветую: не разделяю взгляд автора на MVP, точнее просто придерживаюсь другого, который мне кажется несколько проще. У меня предъявитель и представления связаны прямо по Command, а в обратную сторону по Observer, то есть представление реализует интерфейс оповещения, в принципе, некоторая аналогия с вашим вариантом есть, но не берусь судить.

S>модель неактивного Presenter'а

Это пять!
Что за чудо-юдо-то такое?

S>Стоит ли для каждого диалога делать интерфейс, чтобы постредством него Presenter манипулировал ими наравне с остальными View'ами ?

Да, стоит. Чем диалог не представление-то? Ответьте сами себе на такой простой вопрос: если данные модели изменяться уже после открытия диалога, то есть представления, которое ее отображает, должен ли на это как-то среагировать диалог, к примеру, обновиться, показав актуальные данные или продолжать казать дела минувших дней? Или такой: пользователь через диалог изменяет данные, должны ли оно (это изменение) мгновенно (или даже вообще просто после закрытия диалога) отобразиться где-то в экранной форме? В зависимости от ответа на этот вопрос и решайте.
Re[14]: Спасибо.
От: shvonder Россия  
Дата: 22.11.07 15:56
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Здравствуйте, shvonder, Вы писали:

S>>модель неактивного Presenter'а
R>Это пять!
R>Что за чудо-юдо-то такое?
Очепятка. Читать — пассивный Viewer. Пассивный, активный, так и просится на язык нетехнический термин

R>Или такой: пользователь через диалог изменяет данные, должны ли оно (это изменение) мгновенно (или даже вообще просто после закрытия диалога) отобразиться где-то в экранной форме?

Должно. В общем пока такое сложилось мнение: MVP Бодягина
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.

реализовывать мучительно.
Re[15]: Спасибо.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 22.11.07 16:19
Оценка:
Здравствуйте, shvonder, Вы писали:

S>Очепятка. Читать — пассивный Viewer. Пассивный, активный, так и просится на язык нетехнический термин

Честно говоря, такого термина тоже не встречал, хотя понял, что вы подразумеваете. В отношении MVC термины активность/пассивность употребляют по отношению к модели (после описания оригинальной реализации в Smalltalk аж лет 30 назад).

S>Должно. В общем пока такое сложилось мнение: MVP Бодягина
Автор(ы): Иван Бодягин
Дата: 25.07.2006
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Основная причина такой неоднозначности в том, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
реализовывать мучительно.

Сколько программистов, столько и видений MVC/MVP. По-моему, в этом нет ничего плохого: каждый видит мир по-разному, соответственно на объектах каждому, возможно, бывает удобнее несколько по-своему построить взаимодействия сущностей. Кстати, оригинальное описание MVC в Smalltalk спокойно допускает такие всевозможные трактования (задаются только основные правила игры, а нюансы каждый может выбрать по вкусу). Возможно, вам чисто психологически удобнее видеть сущности MVC-триады несколько иначе, нежели предлагает IB. У меня и вовсе иное видение: если интересно, см. другую статью про MVC на сайте.
Re[16]: Спасибо.
От: shvonder Россия  
Дата: 22.11.07 16:36
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Возможно, вам чисто психологически удобнее видеть сущности MVC-триады несколько иначе, нежели предлагает IB. У меня и вовсе иное видение: если интересно, см. другую статью про MVC на сайте.


На самомо деле я стрепетом жду момента, когда соберу наконец хелло ворд на VC с wxWindows, и буду переходить на студию. Новый проект решил сделать максимально переносимым в том плане, чтобы менять гуй малой кровью. А тут Бодягин и говорит: "хлопцы, ща покажу", и даже спорит с неверующими и даже убедительно. Ладно, поживём увидим.
Re[17]: Спасибо.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 22.11.07 16:54
Оценка:
Здравствуйте, shvonder, Вы писали:

S>На самомо деле я стрепетом жду момента, когда соберу наконец хелло ворд на VC с wxWindows, и буду переходить на студию. Новый проект решил сделать максимально переносимым в том плане, чтобы менять гуй малой кровью. А тут Бодягин и говорит: "хлопцы, ща покажу", и даже спорит с неверующими и даже убедительно. Ладно, поживём увидим.

Вообще говоря, стоит прислушаться к словам IB. То, что вы не смогли разобраться с его видением MVP, говорит только об одном и это "одно" — вовсе не то, что вы написали выше.
Re[18]: Спасибо.
От: shvonder Россия  
Дата: 22.11.07 18:10
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Вообще говоря, стоит прислушаться к словам IB. То, что вы не смогли разобраться с его видением MVP, говорит только об одном и это "одно" — вовсе не то, что вы написали выше.

Никто не говорит, что IB неправ. Просто моя попытка реализовать IB-MVP мне самому не нравиться, ну я и спросил. Вопросов то много. Как так лихо Виду удаётся вызывать нужные процедуры Презентера, при том, что вид о нём даже не знает

  public class Presenter
   {
      private Model _model = new Model();
      private IView _view;
     public Presenter(IView view)
      {
         _view = view;
         _view.SetCelsius += new EventHandler<EventArgs>(OnSetCelsius);//<---- !!!
         _view.SetFarenheit += new EventHandler<EventArgs>(OnSetFarenheit);
         RefreshView();
      }

Сдаётся, что на C++ такого не сделать. Лучше чем слать сообщения интерфейсу этого класса, я пока не придумал.
Прошу прощения за многословность, но тема интересная, а попытки поспрошать в форуме обычно заканчиваются какой то ерундой.
Re[19]: Спасибо.
От: Экселенц Россия  
Дата: 22.11.07 18:54
Оценка:
S>Сдаётся, что на C++ такого не сделать. Лучше чем слать сообщения интерфейсу этого класса, я пока не придумал.
На С++ это делается практически так же, как и в NET, если использовать boost::function или аналоги.

class IView {
public:
    boost::function<void (int)> SetCelsius;
};

class Presenter {
public:
    Presenter(IView* view) {
        view->SetCelsius = boost::bind(&Presenter::OnSetCelsius, this, _1);
    }

private:
    void OnSetCelsius(int n);
};


А вот на каждый чих городить IView действительно достаёт.
Re[19]: Спасибо.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 23.11.07 04:39
Оценка:
Здравствуйте, shvonder, Вы писали:

S>Лучше чем слать сообщения интерфейсу этого класса, я пока не придумал.

Статью IB читал уже давно, но разве он не имеено так и предлагал?

S>Прошу прощения за многословность, но тема интересная, а попытки поспрошать в форуме обычно заканчиваются какой то ерундой.

Взаимодействие представления и предъявителя мы обсуждали в теме обсуждения его статьи, посмотрите ее: я предлагал в ней альтернативные варианты — конкретно, помню, мне не очень нравилось, что при таком построении связи нет возможности прицепить к одному предъявителю множество представлений.
Re[20]: Спасибо.
От: Экселенц Россия  
Дата: 23.11.07 07:54
Оценка: 1 (1)
Здравствуйте, rsn81, Вы писали:

R>помню, мне не очень нравилось, что при таком построении связи нет возможности прицепить к одному предъявителю множество представлений.

Ну почему же, мы ведь можем реализовать в предьявителе специальный интерфейс для поддержки этой возможности, примерно так:

class IView {
public:
    boost::function<void (IView*, int)> SetCelsius;
};

class Presenter {
public:
    Presenter();

    void AddView(IView* view) {
        view->SetCelsius = boost::bind(&Presenter::OnSetCelsius, this, _1, _2);
        
        _views.push_back(view);
    }

private:
    void OnSetCelsius(IView* view, int n) {
        // обновляем все view из массива _views;
    }

    std::vector<View*> _views;
};


Здесь я добавил параметр IView* к коллбэку, чтобы предъявитель знал, какое представление его вызвало, если это знание не нужно, его можно убрать.
По большому счёту получился тот же обсервер, но немного более гибкий. Отличие заключается в том, что по обсерверу для подписки на сообщения представление должно получить указатель/ссылку на объект класса, реализующего некий интерфейс IPublisher (у которого есть метод void Subscribe(IObserver*) ). В приведённом же варианте абсолютно любой класс может настроить коллбэки под себя и получать сообщения от представления. Но в остальном, не спорю, решения почти эквивалентны.
Что же касается главного вопроса топика про модальные диалоги, то на мой дилетанский взгляд не нужно для каждого из них лепить новый интерфейс IView. Способ ввода параметров — это внутреннее дело каждого представления, т.е. этот модальный диалог как бы часть представления, такая же, как и контролы, которые на нём лежат.
Re[21]: Спасибо.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 23.11.07 08:13
Оценка:
Здравствуйте, Экселенц, Вы писали:

Э>Ну почему же, мы ведь можем реализовать в предьявителе специальный интерфейс для поддержки этой возможности, примерно так:

[skipped]
Именно так и делаю. Просто в этом случае потребность в том виде IView, который предлагает IB, нивелируется, нет, оно возможно, но мне кажется более удобным здесь становится озвученное выше т.н. "активное" представление. Да, оно реализует простой контракт подписки ISubscriber, по которому получает оповещения от предъявителя (при этом или получая информацию об изменении модели в самом оповещении, или самостоятельно вытягивая эту информацию из предъявителя). То есть, если ничего не путаю, конечно, у вас немного сложнее: IView + Callback — а здесь только ISubscriber.

Здесь еще дополнительная фишка выстреливает. Так как представление является всего лишь подписчиком, то оно может отписаться от одного предъявителя и подписаться на события другого. Чувствуете применимость? К примеру, проводник Windows: при выборе в дереве иерархии папок конкретной, боковое представление содержимого папки переключается на отображение выбранной папки (отписывается от одного предъявителя, подключается к другому). Возможен случай, когда представление вообще ничего не отображает: не подключено ни к одному предъявителю.
Re[22]: Спасибо.
От: Экселенц Россия  
Дата: 23.11.07 11:25
Оценка:
Здравствуйте, rsn81, Вы писали:

R>Именно так и делаю. Просто в этом случае потребность в том виде IView, который предлагает IB, нивелируется, нет, оно возможно, но мне кажется более удобным здесь становится озвученное выше т.н. "активное" представление. Да, оно реализует простой контракт подписки ISubscriber, по которому получает оповещения от предъявителя (при этом или получая информацию об изменении модели в самом оповещении, или самостоятельно вытягивая эту информацию из предъявителя). То есть, если ничего не путаю, конечно, у вас немного сложнее: IView + Callback — а здесь только ISubscriber.


Всё таки мне кажется, что количество связей в обоих случаях одинаково. У вас же представление должно как-то общаться с предъявителем или моделью, например, сообщить, что пользователь выбрал новую папку в дереве папок проводника. Значит, где-то будет метод SetSelectedDir(String dir). Это метод можно вызвать либо явно, если представление имеет ссылку на предъявителя/модель, как, наверное, у вас, либо через callback. Т.е. я хочу сказать, что только интерфейса ISubscriber мало.

R>Здесь еще дополнительная фишка выстреливает. Так как представление является всего лишь подписчиком, то оно может отписаться от одного предъявителя и подписаться на события другого. Чувствуете применимость? К примеру, проводник Windows: при выборе в дереве иерархии папок конкретной, боковое представление содержимого папки переключается на отображение выбранной папки (отписывается от одного предъявителя, подключается к другому). Возможен случай, когда представление вообще ничего не отображает: не подключено ни к одному предъявителю.


Мне видится, что это классический подход MVC, в котором нет ничего плохого В MVP же я вижу решение этой задачи следующим образом. У правого IView в интерфейсе есть метод ShowItems(Vector<Item>). В ответ на изменение текущей папки в левом представлении (дереве папок) предъявитель получает у модели содержимое этой новой папки и вызывает у правого представления метод ShowItems, передавая новое содержимое (здесь Item описывает элемент файловой системы (папку, файл...)). Т.е. представлению просто не нужно подписываться и отписываться на события, всем управляет предъявитель.

Но я не противопоставляю ваш подход своему, скажу банальность, но в разных ситуациях проще и лучше могут оказаться разные подходы. Я просто подсказал автору топика, как на С++ сделать то же самое, что и на NET в статье, если он захочет Хотя не скрою, в целом пассивная модель мне нравится больше и сам я стараюсь оставаться в её рамках, если другой подход не сулит больших преимуществ.
Re[23]: Спасибо.
От: rsn81 Россия http://rsn81.wordpress.com
Дата: 24.11.07 08:45
Оценка:
Здравствуйте, Экселенц, Вы писали:

Э>Всё таки мне кажется, что количество связей в обоих случаях одинаково. У вас же представление должно как-то общаться с предъявителем или моделью, например, сообщить, что пользователь выбрал новую папку в дереве папок проводника. Значит, где-то будет метод SetSelectedDir(String dir). Это метод можно вызвать либо явно, если представление имеет ссылку на предъявителя/модель, как, наверное, у вас, либо через callback. Т.е. я хочу сказать, что только интерфейса ISubscriber мало.

Представление выбирает нужный ему предъявитель из локатора предъявителей (см. шаблон проектирования Service Locator), это чтобы избежать неприятностей с Singleton. Разумеется, общение представления и предъявителя в части изменения данных подразумевает интерфейс со стороны предъявителя — использую шаблон проектирования Command. Говорил выше немного о другом: о том, что на представление налагается всего один контракт — подписки; а предъявителю не так важно, кто получает его уведомления — все, кто подписался (в принципе, это может быть любой заинтересованный класс, то есть представление не обязательно подразумевает какое-либо графическое отображение).

Э>Мне видится, что это классический подход MVC, в котором нет ничего плохого В MVP же я вижу решение этой задачи следующим образом. У правого IView в интерфейсе есть метод ShowItems(Vector<Item>). В ответ на изменение текущей папки в левом представлении (дереве папок) предъявитель получает у модели содержимое этой новой папки и вызывает у правого представления метод ShowItems, передавая новое содержимое (здесь Item описывает элемент файловой системы (папку, файл...)). Т.е. представлению просто не нужно подписываться и отписываться на события, всем управляет предъявитель.

Угу, так и описывал IB. Просто в статье не был затронут аспект работы с одними данными (моделью) нескольких представлений.

Э>Но я не противопоставляю ваш подход своему, скажу банальность, но в разных ситуациях проще и лучше могут оказаться разные подходы. Я просто подсказал автору топика, как на С++ сделать то же самое, что и на NET в статье, если он захочет Хотя не скрою, в целом пассивная модель мне нравится больше и сам я стараюсь оставаться в её рамках, если другой подход не сулит больших преимуществ.

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