Связь между контроллером и видом - PullRequest
2 голосов
/ 07 апреля 2010

Лакмусовый тест для меня для хорошей реализации MVC - насколько легко поменять местами вид. Я всегда делал это очень плохо из-за лени, но теперь я хочу сделать это правильно. Это на C ++, но оно должно применяться в равной степени к приложениям, не относящимся к рабочему столу, если верить обману.

Вот один пример: контроллер приложения должен проверить какой-либо URL на наличие в фоновом режиме. Он может подключиться к событию «URL available» (с использованием Boost Signals) следующим образом:

BackgroundUrlCheckerThread(Controller & controller)
{
   // ...
   signalUrlAvailable.connect(
      boost::bind(&Controller::urlAvailable,&controller,_1))
}

Так как же Controller::urlAvailable выглядит?

Вот одна из возможностей:

void
Controller::urlAvailable(Url url)
{
    if(!view->askUser("URL available, wanna download it?"))
      return;
    else
      // Download the url in a new thread, repeat
}

Мне это кажется грубым соединением вида и контроллера. Такое соединение делает невозможным реализацию вида при использовании полотна (кроме сопрограмм.)

Другая возможность:

void
Controller::urlAvailable(Url url)
{
   urlAvailableSignal(url); // Now, any view interested can do what it wants
}

Я неравнодушен к последнему, но кажется, что если я сделаю это, то будет:

  1. 40 миллиардов таких сигналов. Контроллер приложения может стать огромным для нетривиального приложения
  2. Очень реальная возможность того, что данное представление случайно игнорирует некоторые сигналы (API могут информировать вас во время соединения, но сигналы / слоты находятся во время выполнения)

Так что вы предлагаете удалить сцепление, а также уменьшить сложность? Заранее спасибо.

Ответы [ 2 ]

3 голосов
/ 07 апреля 2010

Лакмусовый тест для меня для хорошей реализации MVC - насколько легко поменять представление.

Я, вероятно, подожгу, если скажу это, но я не согласен с этим утверждением. На бумаге это выглядит хорошо, но примеры из реальной жизни показывают, что хороший пользовательский интерфейс отзывчив и интерактивен, что часто требует переплетения вида и контроллера. Попытка кодирования полностью универсального контроллера для обработки непредвиденных теоретических представлений добавляет тонну кода и усложняет как контроллер (ы), так и представления. В моем опыте взаимосвязанные представления / контроллер работали лучше - я думаю об этом как "M (VC)".

Я бы сказал, лакмусовая бумажка для хорошей реализации MVC - это то, как легко вы можете «добавить» другую пару вида / контроллера в модель. Распространяются ли изменения модели с одного вида / контроллера (например, оператора рабочего стола) на другой вид / контроллер (например, удаленного пользователя сети). Достаточно ли универсальна модель для поддержки различных парадигм вида / контроллера (например, графический интерфейс рабочего стола, командная строка, запланированный / пакетный ввод, веб-интерфейс, веб-служба и т. Д.)?

Это не означает, что код контроллера не может быть общим (например, получен из общей базы), но вы должны найти правильную линию между тем, что должно обрабатываться контроллером (внешнее манипулирование моделью) и что следует считать частью поведения модели (внутренние переходы модели). То же самое для просмотра кода.

Я думаю, что чтение некоторых ответов в разделе "Что входит в" Контроллер "в" MVC " также поможет в этом.

0 голосов
/ 07 апреля 2010

Вы разделяете их, используя 'm' - Модель и используйте (в концепции) шаблон, подобный команде, и шаблон слушателя, чтобы уменьшить сложность.

Таким образом, ваш контроллер может выглядеть так:

void
Controller::urlAvailable(Url url)
{
   Controller::fireSignal("urlAvailable", url, ... other possible parameter);
}
Controller::fireSignal(char* cmd, Url url, ... other possible parameters) {
   Model &M   = new Model();
   M->command = cmd;
   M->url     = url;
   M-> ... other possible
   for(int v = Controller::ViewCount; --v >= 0; )
      Controller::Views[v]->notice(M);
}

ПРИМЕЧАНИЕ: я не программист на C ++, поэтому прости меня за неправильную грамматику.

Вся идея MVC состоит в том, чтобы использовать M (odel) для отделения C (ontrol) от V (iew).Пример чрезвычайно упрощен.Более практичным является использование другой модели для различного вида аналогичного сигнала.

Надеюсь, это поможет.

...