разделение кода на графику и управление
От: cupuyc  
Дата: 26.07.09 10:10
Оценка:
как-то слышал о концепции, в которой код разделяются на 3 части:

1. занимается только отображением графики
2. занимается только вычислениями
3. осуществляет взаимодействие первых двух

Что касается реализации. Допустим есть 3 класса: CAnyUi (гуя), CAnyCtrl (считалка), CAny (должен ими рулить). Допустим CAnyUi ловит оконное сообщение. есть обработчик этого сообщения CAnyUi::on_command(). это сообщение по идее, должен обработать CAnyCtrl. Так вот вопрос — как можно передать это сообщение CAnyCtrl не нарушив данной концепции?

1. заюзать множественное наследование: CAny : public CAnyUi, public CAnyCtrl. соответственно появляется возможность на своё усмотрение переопределять метод CAnyUi::on_command() и вызывать соответствующий метод CAnyCtrl.

2. добавить в CAnyUi колбек обработчик. то есть на on_command функция, которая уже вызывает соответствующий метод CAnyCtrl.

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

07.08.09 15:58: Перенесено модератором из 'Алгоритмы' — Кодт
Re: разделение кода на графику и управление
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 26.07.09 10:22
Оценка:
Здравствуйте, cupuyc, Вы писали:

C>как-то слышал о концепции, в которой код разделяются на 3 части:


C>1. занимается только отображением графики

C>2. занимается только вычислениями
C>3. осуществляет взаимодействие первых двух

Model — View — Controller со всеми вариациями. Вообще-то если Вы поищете по RSDN по этим словам — найдёте очень много интересного.

C>Что касается реализации. Допустим есть 3 класса: CAnyUi (гуя), CAnyCtrl (считалка), CAny (должен ими рулить). Допустим CAnyUi ловит оконное сообщение. есть обработчик этого сообщения CAnyUi::on_command(). это сообщение по идее, должен обработать CAnyCtrl. Так вот вопрос — как можно передать это сообщение CAnyCtrl не нарушив данной концепции?


C>1. заюзать множественное наследование: CAny : public CAnyUi, public CAnyCtrl. соответственно появляется возможность на своё усмотрение переопределять метод CAnyUi::on_command() и вызывать соответствующий метод CAnyCtrl.


C>2. добавить в CAnyUi колбек обработчик. то есть на on_command функция, которая уже вызывает соответствующий метод CAnyCtrl.


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

C>собственно вопрос. может я что-то упускаю? множественное наследование юзать неохота, да и с колбеками как-то криво получится...


С коллбэками — да, их надо творить на каждое действие (функцией-скопом или раздельно — это уже как удобнее), но получится то что надо.
The God is real, unless declared integer.
Re[2]: разделение кода на графику и управление
От: cupuyc  
Дата: 26.07.09 10:49
Оценка:
тогда такой вопрос. как лучше реализовать колбеки? можно опять-же унаследовать класс, типа:

CAny : public CAnyUi

и перехваченые меоды — по сути дела колбеки. или же в самом CAnyUi хранить список указателей на функции и вызывать их в соответствующих методах?
Re[3]: разделение кода на графику и управление
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 26.07.09 11:00
Оценка:
Здравствуйте, cupuyc, Вы писали:

C>тогда такой вопрос. как лучше реализовать колбеки? можно опять-же унаследовать класс, типа:


Прошу не срезать существенное в квотинге. Не всем удобен древовидный показ.

C>CAny : public CAnyUi


C>и перехваченые меоды — по сути дела колбеки.


Нет.

C> или же в самом CAnyUi хранить список указателей на функции и вызывать их в соответствующих методах?


Вариант 1 — ручное заполнение списка коллбэков. Иногда хорошо, но обычно громоздко.
Вариант 2 — производить CAnyCtrl от чисто виртуального класса (интерфейса) с нужными коллбэками (назовём CAnyUICallback) и в реализации CAnyCtrl писать для них методы. В CAnyUI передавать указатель на объект CAnyCtrl, но храниться там он будет как CAnyUICallback*.
Вариант 3 — оформлять сообщения и передавать их в CAny общему обработчику, который дальше будет или сам в CAnyCtrl передавать раздельно, или вызывать такой же общий обработчик.
Есть ещё много промежуточных вариантов.
The God is real, unless declared integer.
Re: разделение кода на графику и управление
От: Аноним  
Дата: 27.07.09 10:57
Оценка:
я так понимаю, в идеале View и Control вообще не должны явно взаимодействовать? то есть, View посылает сообщения, Control изменяет данные, View отображает изменённые данные. Model ничего не знает о Control и View. Control ничего не знает о View — он лишь реагирует на сообщения, а View может только читать Model и отсылать уведомления Control'у. так?
Re[2]: разделение кода на графику и управление
От: gyraboo  
Дата: 27.07.09 11:45
Оценка:
Здравствуйте, Аноним, Вы писали:

А>я так понимаю, в идеале View и Control вообще не должны явно взаимодействовать? то есть, View посылает сообщения, Control изменяет данные, View отображает изменённые данные. Model ничего не знает о Control и View. Control ничего не знает о View — он лишь реагирует на сообщения, а View может только читать Model и отсылать уведомления Control'у. так?


Заморочаешся кодировать раздельные View и Controller, лучше их объединять.
Re[3]: разделение кода на графику и управление
От: GarryIV  
Дата: 27.07.09 16:08
Оценка:
Здравствуйте, gyraboo, Вы писали:

А>>я так понимаю, в идеале View и Control вообще не должны явно взаимодействовать? то есть, View посылает сообщения, Control изменяет данные, View отображает изменённые данные. Model ничего не знает о Control и View. Control ничего не знает о View — он лишь реагирует на сообщения, а View может только читать Model и отсылать уведомления Control'у. так?


G>Заморочаешся кодировать раздельные View и Controller, лучше их объединять.


Замучаешься если во view все запихать. А так если уметь готовить то все хоккей.
WBR, Igor Evgrafov
Re[3]: разделение кода на графику и управление
От: Аноним  
Дата: 28.07.09 03:08
Оценка:
Здравствуйте, gyraboo, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


А>>я так понимаю, в идеале View и Control вообще не должны явно взаимодействовать? то есть, View посылает сообщения, Control изменяет данные, View отображает изменённые данные. Model ничего не знает о Control и View. Control ничего не знает о View — он лишь реагирует на сообщения, а View может только читать Model и отсылать уведомления Control'у. так?


G>Заморочаешся кодировать раздельные View и Controller, лучше их объединять.


чем лучше? может проще? понятно что на первом этапе будет проще. а если ты вместо GDI захочешь сделать OpenGL — переписывать всю графику, так ещё и управление?
Re: разделение кода на графику и управление
От: Sealcon190 Соломоновы острова  
Дата: 28.07.09 05:55
Оценка:
Здравствуйте, cupuyc, Вы писали:

C>как-то слышал о концепции, в которой код разделяются на 3 части:


C>1. занимается только отображением графики

C>2. занимается только вычислениями
C>3. осуществляет взаимодействие первых двух

А в чём принципиальная разница по сравнению с обычным представлением документ-вид, где вся расчётная часть находится в отдельном длл или ком-объекте?
Re[4]: разделение кода на графику и управление
От: gyraboo  
Дата: 28.07.09 07:57
Оценка:
Здравствуйте, Аноним, Вы писали:

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


G>>Здравствуйте, Аноним, Вы писали:


А>>>я так понимаю, в идеале View и Control вообще не должны явно взаимодействовать? то есть, View посылает сообщения, Control изменяет данные, View отображает изменённые данные. Model ничего не знает о Control и View. Control ничего не знает о View — он лишь реагирует на сообщения, а View может только читать Model и отсылать уведомления Control'у. так?


G>>Заморочаешся кодировать раздельные View и Controller, лучше их объединять.


А>чем лучше? может проще? понятно что на первом этапе будет проще. а если ты вместо GDI захочешь сделать OpenGL — переписывать всю графику, так ещё и управление?


Скорее всего не захочу.
А лучше — тем что обычно вид-контроллер так связаны, что если приходится переписывать вид, то и систему контроллеров тоже.
Насчет GDI/OpenGL — эту часть я бы вообще к виду как части MVC не относил. Ведь под видом понимается логический вид, содержащий элементы интерфейса
и структуры данных, связывающие их с соотв.элементами модели, но никак не физическая реализация рендеринга.
При правильной реализации MVC замена одного рендерера другим вообще не должна затрагивать mvc-вид.
Re[5]: разделение кода на графику и управление
От: Аноним  
Дата: 28.07.09 08:07
Оценка:
G>Скорее всего не захочу.
G>А лучше — тем что обычно вид-контроллер так связаны, что если приходится переписывать вид, то и систему контроллеров тоже.
G>Насчет GDI/OpenGL — эту часть я бы вообще к виду как части MVC не относил. Ведь под видом понимается логический вид, содержащий элементы интерфейса
G>и структуры данных, связывающие их с соотв.элементами модели, но никак не физическая реализация рендеринга.
G>При правильной реализации MVC замена одного рендерера другим вообще не должна затрагивать mvc-вид.

я имею ввиду именно графику. именно отображение информации конечному пользователю. нужно, например, написать шахматы:
— массив с фигурками — Model
— логика игры (перемещение фигур, определение выигровшего и т.п.) — Control
— окошко с нарисованными на нём фигурами — View.

следовательно: юзер перемещает фигуру — View, получив соответствующее оконное сообщение, отправляет уведомление Control'у. Control получает уведомление, анализирует его и, если надо, модифицирует Model. Затем View отображает Model.
вот и получаем что View работает только с окошками, Control — только с логикой, Model просто хранит данные и организует доступ к ним.
Re[6]: разделение кода на графику и управление
От: gyraboo  
Дата: 28.07.09 10:19
Оценка:
Здравствуйте, Аноним, Вы писали:

А>я имею ввиду именно графику. именно отображение информации конечному пользователю. нужно, например, написать шахматы:

А> — массив с фигурками — Model
А> — логика игры (перемещение фигур, определение выигровшего и т.п.) — Control

Не, вот тут неправильно. Логика игры находится тоже в модели. Контроллер же отвечает за соответствие модели-вида тому что изменяет пользователь.
Т.е. его задача только в том чтобы считать input и изменить вид и/или модели.


А> — окошко с нарисованными на нём фигурами — View.


А>следовательно: юзер перемещает фигуру — View, получив соответствующее оконное сообщение, отправляет уведомление Control'у. Control получает уведомление, анализирует его и, если надо, модифицирует Model. Затем View отображает Model.

А>вот и получаем что View работает только с окошками, Control — только с логикой, Model просто хранит данные и организует доступ к ним.

Получается так:
— юзер клинул на фигуру которую хочет переместить
— контроллер перехватил клик мышки и оповестил модель
— модель изменила "активную фигуру"
— вид, подписанный на это изменение, перерисовывает активную фигуру, скажем выделяет её мерцанием
— юзер кликает в новую клетку куда перемещать фигуру
— контроллер перехватывает клик и оповещает модель
— модель перемещает фигуру и оповещает вид об этом
— вид перерисовыват фигуру на новом месте
Re[7]: разделение кода на графику и управление
От: Аноним  
Дата: 28.07.09 11:19
Оценка:
G>Получается так:
G> — юзер клинул на фигуру которую хочет переместить
G> — контроллер перехватил клик мышки и оповестил модель
G> — модель изменила "активную фигуру"
G> — вид, подписанный на это изменение, перерисовывает активную фигуру, скажем выделяет её мерцанием
G> — юзер кликает в новую клетку куда перемещать фигуру
G> — контроллер перехватывает клик и оповещает модель
G> — модель перемещает фигуру и оповещает вид об этом
G> — вид перерисовыват фигуру на новом месте

нет, что-то я не допонимаю.
1. обработкой оконных сообщений занимается только View.
2. пришло сообщение WM_LBUTTONDOWN => view вызвал соответствующий обработчик из таблицы (типа on_selecting_cell(column, line)). таблица — массив указателей, или указатель на базовый виртуальный класс (vftable).
3. контроллер — конкретная реализация этого абстрактного класса. вызвался метод on_selecting_cell — контроллер вызывает соответствующий метод модели.

вопрос — зачем контроллер, если on_selecting_cell может напрямую идти модели? возможно, может быть проблема лишь с реализацией — придётся наследовать модель от абстрактного класса, которому передаёт сообщения View. но это, вообще говоря, не проблема.
Re[8]: разделение кода на графику и управление
От: gyraboo  
Дата: 28.07.09 11:36
Оценка:
Здравствуйте, Аноним, Вы писали:

G>>Получается так:

G>> — юзер клинул на фигуру которую хочет переместить
G>> — контроллер перехватил клик мышки и оповестил модель
G>> — модель изменила "активную фигуру"
G>> — вид, подписанный на это изменение, перерисовывает активную фигуру, скажем выделяет её мерцанием
G>> — юзер кликает в новую клетку куда перемещать фигуру
G>> — контроллер перехватывает клик и оповещает модель
G>> — модель перемещает фигуру и оповещает вид об этом
G>> — вид перерисовыват фигуру на новом месте

А>нет, что-то я не допонимаю.

А>1. обработкой оконных сообщений занимается только View.
А>2. пришло сообщение WM_LBUTTONDOWN => view вызвал соответствующий обработчик из таблицы (типа on_selecting_cell(column, line)). таблица — массив указателей, или указатель на базовый виртуальный класс (vftable).
А>3. контроллер — конкретная реализация этого абстрактного класса. вызвался метод on_selecting_cell — контроллер вызывает соответствующий метод модели.

А>вопрос — зачем контроллер, если on_selecting_cell может напрямую идти модели? возможно, может быть проблема лишь с реализацией — придётся наследовать модель от абстрактного класса, которому передаёт сообщения View. но это, вообще говоря, не проблема.


Верно, отдельный контроллер нафиг не нужен, его с видом объединять нужно, например как ты и описал.
Re[9]: разделение кода на графику и управление
От: cupuyc  
Дата: 28.07.09 12:57
Оценка:
Здравствуйте, gyraboo, Вы писали:

G>Здравствуйте, Аноним, Вы писали:


G>>>Получается так:

G>>> — юзер клинул на фигуру которую хочет переместить
G>>> — контроллер перехватил клик мышки и оповестил модель
G>>> — модель изменила "активную фигуру"
G>>> — вид, подписанный на это изменение, перерисовывает активную фигуру, скажем выделяет её мерцанием
G>>> — юзер кликает в новую клетку куда перемещать фигуру
G>>> — контроллер перехватывает клик и оповещает модель
G>>> — модель перемещает фигуру и оповещает вид об этом
G>>> — вид перерисовыват фигуру на новом месте

А>>нет, что-то я не допонимаю.

А>>1. обработкой оконных сообщений занимается только View.
А>>2. пришло сообщение WM_LBUTTONDOWN => view вызвал соответствующий обработчик из таблицы (типа on_selecting_cell(column, line)). таблица — массив указателей, или указатель на базовый виртуальный класс (vftable).
А>>3. контроллер — конкретная реализация этого абстрактного класса. вызвался метод on_selecting_cell — контроллер вызывает соответствующий метод модели.

А>>вопрос — зачем контроллер, если on_selecting_cell может напрямую идти модели? возможно, может быть проблема лишь с реализацией — придётся наследовать модель от абстрактного класса, которому передаёт сообщения View. но это, вообще говоря, не проблема.


G>Верно, отдельный контроллер нафиг не нужен, его с видом объединять нужно, например как ты и описал.


прошу прощения. ступил. всё. дошло. контроллер только лишь занимается отсылкой сообщений модели.
Re: разделение кода на графику и управление
От: Ruslan.Yusupov Россия  
Дата: 07.08.09 12:18
Оценка: +1
Здравствуйте, cupuyc, Вы писали:

C>как-то слышал о концепции, в которой код разделяются на 3 части:


C>1. занимается только отображением графики

C>2. занимается только вычислениями
C>3. осуществляет взаимодействие первых двух

C>Что касается реализации. Допустим есть 3 класса: CAnyUi (гуя), CAnyCtrl (считалка), CAny (должен ими рулить). Допустим CAnyUi ловит оконное сообщение. есть обработчик этого сообщения CAnyUi::on_command(). это сообщение по идее, должен обработать CAnyCtrl. Так вот вопрос — как можно передать это сообщение CAnyCtrl не нарушив данной концепции?


C>1. заюзать множественное наследование: CAny : public CAnyUi, public CAnyCtrl. соответственно появляется возможность на своё усмотрение переопределять метод CAnyUi::on_command() и вызывать соответствующий метод CAnyCtrl.


C>2. добавить в CAnyUi колбек обработчик. то есть на on_command функция, которая уже вызывает соответствующий метод CAnyCtrl.


C>собственно вопрос. может я что-то упускаю? множественное наследование юзать неохота, да и с колбеками как-то криво получится...


Почитай про паттерны MVP [Model-View-Presenter] и MVC [Model-View-Controller] — выберешь, что тебе больше подходит.
А не хочешь, подписать на оконное событие сам CAny [Presenter] (по-хорошему — на событие CAnyUi [View], которое делегирует оконное событие)?
Идея "разделения на 3 части" предполагает повышение заменяемости модулей — "провязывание" зависимостей через интерфейсы, а не через классы.
И для уменьшения количества зависимостей (пусть и от интерфейсов), надо стараться делать так, чтобы только Presenter "знал" про модели [Model] и представления [View], а они про него — нет.
Т.е. вызывать метод CAnyCtrl из CAnyUi — не есть хорошо.
Также, как и делать мешанину, наследуя презентер от модели и представления...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.