Должны ли методы контроллера принимать аргументы?

Учитывая, что в представлении есть виджет выбора файла, а контроллер должен обрабатывать событие выбора файла, мне лучше написать метод контроллера:

public void fileSelected(String filePath){
  //process filePath
}

or

public void fileSelected(){
  String filePath = view.getSelectedFilePath();
  //process filePath
}

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

Но это требует создания множества подробных методов, подобных getSelectedFile на стороне V.

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

Из вашего собственного опыта, какой подход вы предпочитаете?


person Piotr Sobczyk    schedule 27.10.2012    source источник


Ответы (4)


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

Еще одна вещь: если вы хотите попробовать второе решение, я рекомендую использовать ViewFactory для удаления логики представления из контроллера.

person op1ekun    schedule 04.11.2012

Первый подход — это путь;

public void fileSelected(String filePath){
  //process filePath
}

Controller не должен заботиться о том, как выглядит View или как он реализован. Разработчику также становится намного понятнее при создании/обновлении представления знать, чего хочет действие в контроллере. Также это упрощает перегрузку методов.

Хотя я действительно не знаю, как будет работать String filePath = view.getSelectedFilePath();. Мы говорим о разборе кода/разметки View?

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

Вот когда вы должны создать класс модели представления (скажем, мы назовем его MyViewModel) для хранения всех свойств, которые вам нужно отправить (может быть, 10 свойств), а затем передать это в действии: fileSelected(MyViewModel model). Вот как он предназначен для использования, и с чем вам помогут *ModelBinder в asp.net mvc.

person Mario S    schedule 27.10.2012
comment
В ответ на ваш вопрос: предположим, что мы передаем выбранный путь к файлу в файловой системе (я обновил вопрос). В примере я выбрал пути к файлам, чтобы избежать ненужных дискуссий о том, должен ли View знать о таких классах, как File и т. д., что не имеет отношения к моему вопросу. - person Piotr Sobczyk; 27.10.2012
comment
Да, ваши доводы разумны. Но еще одним недостатком этого подхода является загромождение сигнатур методов в более сложных случаях (необходимо передать более одной вещи). Методы контроллера с 10 аргументами не кажутся особенно чистыми. Как решить эту проблему? - person Piotr Sobczyk; 27.10.2012
comment
@PiotrSobczyk Я не совсем понимаю вас в классе File и в том, что View знает об этом. Зачем View должно знать об этом? - person Mario S; 27.10.2012
comment
@PiotrSobczyk К вашему второму комментарию: я бы создал класс ViewModel (скажем, назовем его MyViewModel) для хранения всех свойств, которые мне нужно отправить (может быть, 10 свойств), а затем я передал бы это в действие: fileSelected(MyViewModel model). Вот как он предназначен для использования, и что * ModelBinder в asp.net mvc поможет вам. - person Mario S; 27.10.2012
comment
Должна ли быть одна специализированная ViewModel для каждого взаимодействия View-Controller (например, выбор файла, отправка формы, установка флажка и т. д., их может быть много) или должна быть только одна ViewModel для обработки всех этих взаимодействий (передается каждому методу контроллера)? Первый вариант может привести к взрыву класса в более сложных случаях, второй вариант — у нас есть один большой объект, представляющий все состояние представления — так почему бы просто не получить эти данные непосредственно из представления? В общем, я бы предпочел первый вариант, если бы решил пойти по этому пути. - person Piotr Sobczyk; 27.10.2012
comment
@PiotrSobczyk В чем ты развиваешься? Asp.net? - person Mario S; 27.10.2012
comment
Я разрабатываю Java, но мой вопрос не зависит от языка и технологии. Я спрашиваю о шаблоне MVC в целом - person Piotr Sobczyk; 27.10.2012
comment
@PiotrSobczyk Хорошо, хотя MVC - это просто шаблон, в разных методах он реализован по-разному. К сожалению, я мало знаю о том, как это реализовано в методах Java. Но я знаю, что в шаблоне ASP.NET MVC есть связыватели моделей, которые упрощают использование модели представления (как я описал ранее). Но в целом вы должны создать модель представления для каждой цели, но вы также можете создать более общую модель. Возможно, работайте с наследованием, если между моделями есть общие свойства. Думаю, лучше задать вопрос, больше связанный с java MVC. - person Mario S; 27.10.2012
comment
Отлично. Спасибо за ваши объяснения и усилия, которые вы вложили в свои ответы. Я очень ценю это! - person Piotr Sobczyk; 27.10.2012

Я думаю, вам нужно взглянуть на это с шага назад.

Меньше беспокойтесь о том, как он попадет, и больше заботьтесь о проверке и обнаружении ошибок.

Завтра ваши требования могут измениться и потребовать, чтобы вы получали информацию с помощью другого архитектурного подхода. Вы можете реорганизовать настройку [входы / объект ввода] в базовый класс контроллера или один из нескольких классов для разных доменов контроллера.

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

person New Alexandria    schedule 05.11.2012

Я бы пошел с первым подходом. Он многоразовый и разделяет проблемы. Даже если метод получения filePath в будущем изменится, это не повлияет на функциональность вашего метода.

person jhoanna    schedule 05.11.2012