Тема: Хорошее MVC
Показать сообщение отдельно
Старый 08.02.2014, 22:24
Dukobpa3 вне форума Посмотреть профиль Отправить личное сообщение для Dukobpa3 Найти все сообщения от Dukobpa3
  № 579  
Ответить с цитированием
Dukobpa3
 
Аватар для Dukobpa3

блогер
Регистрация: Oct 2010
Адрес: Киев
Сообщений: 1,678
Записей в блоге: 12
Отправить сообщение для Dukobpa3 с помощью Skype™
Могу своими решениями поделиться разве что.

Изначально было следующим образом:
0. В каждом контроллере есть ссылка на хост, т.е. контейнер, в который он ложит свои вьюхи.
1. Каждый контроллер сам создает свои вью и модели.
3. Есть главный контроллер, в который в качестве хоста передается ссылка на мейн, либо на одного из чилдов мейна. Этот контроллер пихает в свой хост другие контейнеры-спрайты, которые раздает другим контроллерам.
4. Контроллеры в два уровня - главный, и в нем все остальные инитятся. Таким образом главный контроллер как инициализатор всего приложения, он создает остальные контроллеры, они в свою очередь создают свои вью-модели.
5. Общение между контроллерами происходит через главный контроллер, контроллеры диспатчат в него, он там разруливает эти нотификации. Т.е. главный контроллер выступает в роли медиатора для остальных контроллеров.

Плюсы:
- четкое дерево зависимостей.
- каждый модуль системы по сути является контроллером. Сколько контроллеров - столько модулей. Легко отключать включать модули целиком, просто закомментировав создание контроллера.

Минусы:
- часто надо чтоб с одной вью работали разные контроллеры (например контроллер туториала везде свой нос сует, или контроллер квестов)
- то же касается и моделей. При чем с моделями такое гораздо чаще происходит.

Второй мой вариант:
- Я сделал уже три дерева. Убрал из контроллера ссылку на хост. Он не создает вьюху и модель, он получает на них готовую ссылку.
- инициализацтором приложения является мейн. Он инициализирует сначала корневую модель. Потом корневую вью, передает в нее ссылку на корневую модель. Корневая вью инициализирует все свои дочерние вьюхи, передает им ссылки каждой на одну какую-то конкретную модельку из главной модели.
- инициализирует контроллер. Передает ему ссылку на ветку из главной модели и на ветку из главной вью.

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

Минусы:
- Увеличилась связанность.
- Сложнее идентифицировать отдельный "модуль", хотя, по прежнему можно отталкиваться от понятия модуль == контроллер. В некоторых ситуациях это не конает но по большей части ок.


Все другие мои варианты являются производной от первого либо второго варианта.

1. Я делал более жесткое дерево контроллеров, моделей и вьюх. Не два уровня главная-остальные, а именно полноценное дерево всей системы, со всеми вытекающими.

Плюсы:
- Когда вся система собрана и связи между классами налажены, ссылки кому надо переданы - дерево вьюх и дерево моделей становятся хзеркальными по отношению друг к другу, таким образом легко связать самую маленькую модельку кнопочки с самой маленькой вьюшкой кнопочки, на каком бы уровне они не находились. Благодаря этому получаем очень удобный рендер.

Минусы:
- Стало сложнее всю систему собрать и єти саміе ссілки из раздела "плюсы" раскидать куда надо. В инициализации стало больше кода.

2. Я делал какие-то статик манагеры вьюх и моделей. Для общения между контроллерами сделал обсервер.
Плюсы:
- Если не брать в учет инициализатор - связанность в таком проекте очень низкая, могу отключить любую вью, модель или контроллер и ничего не отломается.

Минусы:
- всё инитится в инициализаторе Так что пункт про связанность спорный (получается что отключить одну модель от системы легко, а вот запустить только одну модель - уже проблематично). Тесты писать становится неудобно. Проинитить одну модель не проинитив всё приложение - практически нереально.


//**************************
Как-то так.
По сути больше и вариантов то нет.

Есть вариации последнего моего варианта с манагерами, который реализован через IoC контейнер, там можно ссылки на модели и вью растыкивать посредством метатегов. Но суть и архитектура от этого не меняется.
Код AS3:
[inject]
var model:DesignModel;
То же самое что и:
Код AS3:
var model:DesignModel = ModelManager.getModel(ModelsList.DESIGN_MODEL) as DesignModel;
Просто с манагером весь код видно, даже код из манагера, а с IoC контейнером он спрятан в фреймворке контейнера.

//*************************
Во многих вариантах отказываются от контроллеров в пользу команд. Тут очень спорно и очень зависит от реализации. Например как это реализовано в PureMVC - тонуевонафиг.
Реализация Robotlegs более удобна, но чисто мое субьективное мнение - удобнее с контроллером.
__________________
Кто к нам с чем для чего - тот у нас того от того.