Клуб студентов «Технарь». Уникальный сайт с дипломами и курсовыми для технарей.
Описание:
63 вопроса.
1. Что из перечисленного может быть отнесено к преимуществам шаблона «одиночка»?
· Сокращение числа имен в глобальном адресном пространстве
· Предоставление глобальной точки доступа
· Ускорение начальной инициализации
· Минимизация задержки при обращении в силу статической сущности
2. Верно ли, что отношение агрегации может применяться для изображения иерархических отношений между классами?
· Да
· Нет
3. Задачи какого рода решают структурные шаблоны проектирования?
· Определяют алгоритмы и способы взаимодействия объектов между собой
· Создание различных структур, изменяющих поведение уже существующих объектов
· Повседневные задачи: переадресация работы, обеспечение слабой связности системы и так далее
· Абстрагирование процесса создания экземпляров класса
4. Верно ли то, что существуют такие классы, которые могут иметь один и только один экземпляр?
· Да
· Нет
5. Задачи какого рода решают порождающие шаблоны проектирования?
· Повседневные задачи: переадресация работы, обеспечение слабой связности системы и так далее
· Абстрагирование процесса создания экземпляров класса
· Создание различных структур, изменяющих поведение уже существующих объектов
· Определяют алгоритмы и способы взаимодействия объектов между собой
6. Что из перечисленного может быть отнесено к преимуществам шаблона «итератор»?
· Позволяет поддерживать единообразный интерфейс для доступа к элементам системы
· Позволяет поддерживать несколько активных обходов коллекции
· Итератор не должен владеть всей информацией о коллекции
· Не требует дополнительной иерархии классов
7. Верно ли, что наиболее общим отношением между классами является отношение зависимости?
· Да
· Нет
8. Что из перечисленного может быть отнесено к преимуществам шаблона «наблюдатель»?
· Сокращает цепочку вызовов, необходимую для уведомления наблюдателей об изменении состояния объекта
· Абстрагирует связность объекта и наблюдателей
· Позволяет обеспечить широковещательную рассылку уведомлений
· Повышает степень повторной используемости кода
9. Верно ли то, что отношение композиции является частным случаем отношения агрегации?
· Да
· Нет
10. Верно ли, что Java позволяет создавать массив заранее известных величин?
· Да
· Нет
11. Что из перечисленного может быть отнесено к членам класса?
· Вложенный класс
· Метод
· Объект
· Поле
12. Верно ли, что понятие «суперкласс» является синонимом родительского класса?
· Да
· Нет
13. Задачи какого рода решают основные шаблоны проектирования?
· Повседневные задачи: переадресация работы, обеспечение слабой связности системы и так далее
· Абстрагирование процесса создания экземпляров класса
· Создание различных структур, изменяющих поведение уже существующих объектов
· Определяют алгоритмы и способы взаимодействия объектов между собой
14. Задачи какого рода решают поведенческие шаблоны проектирования?
· Повседневные задачи: переадресация работы, обеспечение слабой связности системы и так далее
· Создание различных структур, изменяющих поведение уже существующих объектов
· Абстрагирование процесса создания экземпляров класса
· Определяют алгоритмы и способы взаимодействия объектов между собой
15. Верно ли, что концепция MVC включает в себя ровно три структурных составляющих: модель, вид и контроллер?
· Да
· Нет
16. Верно ли утверждение о том, что Java является декларативным языком программирования?
· Да
· Нет
17. Верно ли, что программист не может управлять сборкой мусора?
· Да
· Нет
18. Верно ли, что MVC позволяет визуализировать одни и те же данные разными способами без изменения модели?
· Да
· Нет
19. Верно ли, что MVC позволяет подключать к одному виду несколько контроллеров?
· Да
· Нет
20. Верно ли, что для создания десктруктора в Java используется блок finalize?
· Да
· Нет
21. Верно ли, что один абстрактный класс не может являться родительским по отношению к другому абстрактному классу?
· Да
· Нет
22. Верно ли, что абстрактный класс не может иметь экземпляров?
· Да
· Нет
23. Верно ли, что абстрактный класс не может содержать реализаций методов?
· Да
· Нет
24. Верно ли, что в пассивной модели MVC об изменениях данных представление оповещает контроллер?
· Да
· Нет
25. Верно ли, что основная цель использование концепции MVC – разграничение логики работы и визуализации?
· Да
· Нет
26. Верно ли, что основная цель использование концепции MVC – упрощение архитектуру приложения?
· Да
· Нет
27. Верно ли утверждение о том, что Java является императивным языком программирования?
· Да
· Нет
28. Верно ли, что в активной модели MVC об изменениях данных представление оповещает контроллер?
· Да
· Нет
29. Какая команда используется для выполнения байт-кода?
· java
· javac
· javar
· javarun
30. Какие группы шаблонов проектирования обычно выделяют?
· Основные
· Порождающие
· Структурные
· Поведенческие
31. Какие из перечисленных утверждений касательно высокоуровневых шаблонов проектирования верны?
· Высокоуровневые шаблоны также называют архитектурными
· Высокоуровневые шаблоны являются универсальными решениями
· Несмотря на то, что высокоуровневые шаблоны являются универсальными, они учитывают специфические особенности конкретных языков программирования
· Высокоуровневые шаблоны также называют идиомами
32. Какие из предлагаемых утверждений верны?
· Статическим называется член класса, доступ к которому возможен без создания экземпляра
· Создание статического метода возможно только при использовании ключевого слова static
· Статические поля являются общими для всех экземпляров класса
33. Какие из перечисленных требований должны выполняться для создания шаблона «неизменяемый объект» в Java?
· Все поля класса должны иметь модификатор private
· Все методы класса должны быть объявлены с модификатором static
· Ссылка this не должна передаваться вовне во время конструирования объекта
· Класс должен быть объявлен с модификатором final
34. Какая из парадигм программирования является ведущей в языке Java?
· Объектно-ориентированная
· Процедурная
· Событийно-ориентированная
· Компонентно-ориентированная
35. Какое из перечисленных утверждений верно?
· UML создан путем объединения всех существующих подходов проектирования того времени
· UML создан на основе наиболее популярных подходов проектирования того времени
· UML является исторически первым языком моделирования
· Статические поля недоступны экземплярам класса
36. Какие типы связей используют в UML?
· Зависимость
· Ассоциация
· Обобщение
· Реализация
37. Какие типы сущностей выделяют в UML?
· Поведенческие
· Аннотирующие
· Структурные
· Группирующие
38. Какие из перечисленных утверждений касательно низкоуровневых шаблонов проектирования верны?
· Низкоуровневые шаблоны учитывают специфику языка программирования
· Низкоуровневые шаблоны также называют идиомами
· Низкоуровневые шаблоны являются универсальными
· Низкоуровневые шаблоны не используются в прикладных разработках
39. Каково основное назначение статического импорта?
· Позволяет JVM эффективно перенаправлять запросы к классам из других пакетов, принимая во внимание их статическую структуру
· Позволяет обращаться к статическим членам без явного указания класса-владельца
· Добавляет в область видимости описываемого класса все статические структуры из указанного пакета
40. Что из перечисленного может быть отнесено к преимуществам шаблона «цепочка ответственности»?
· Гарантирует, что рано или поздно запрос будет обработан
· Позволяет ослабить связи внутри системы
· Не требует дополнительной иерархии классов
· Придает дополнительную гибкость при распределении обязанностей
41. Какое количество секций может содержать блок описания интерфейса на UML-диаграмме классов?
· Одну
· Две
· Три
· Четыре
42. Какое количество секций может содержать блок описания класса на UML-диаграмме классов?
· Одну
· Три
· Две
· Четыре
43. Какое ключевое слово может быть использовано для обращения экземпляра класса к самому себе?
· this
· super
· instanceof
· own
44. Как расшифровывается аббревиатура UML?
· Unified Modeling Language
· Universally Modeling Language
· Unified Modern Language
· Universally Modern Luggage
45. Что из перечисленного может быть отнесено к преимуществам шаблона «адаптер»?
· Увеличивает степень независимости системы от сторонних библиотек
· Смена библиотек не требует изменения всей системы
· Ускорение начальной инициализации
· Минимизация задержки при обращении
46. Что из перечисленного может быть отнесено к преимуществам шаблона «делегирование»?
· Позволяет изменить поведение избегая наследования
· Повышает степень абстракции
· Положительно сказывается на времени обработки запроса системой
· Сокращает число элементов в адресном пространстве
47. Что из перечисленного может быть отнесено к преимуществам шаблона «декоратор»?
· Позволяет динамически добавлять объектам новые обязанности
· Упрощает структуру отдельных классов
· Сокращает количество имен в адресном пространстве
· Не требует дополнительной иерархии классов
48. Что из перечисленного может быть отнесено к недостаткам шаблона «отложенная инициализация»?
· Не позволяет явным образом задать порядок инициализации
· Вносит дополнительную задержку при обращении к объекту
· Порождает дополнительные ошибки при многопоточной работе
· Замедляет инициализацию объектов
49. Что из перечисленного может быть отнесено к преимуществам шаблона «заместитель»?
· Позволяет инициализировать объекты по требованию
· Позволяет придать объектам дополнительный функционал
· Сокращает время отклика системы
· Не требует создания новых объектов
50. Что из перечисленного может быть отнесено к преимуществам шаблона «команда»?
· Позволяет параметризировать объекты выполняемым действием
· Позволяет обрабатывать запросы как объекты
· Упрощает иерархию классов
· Уменьшает время отклика системы
51. Что из перечисленного может быть отнесено к преимуществам шаблона «компоновщик»?
· Упрощает архитектуру приложения
· Упрощает процедуру добавления новых компонентов в систему
· Позволяет единообразно работать с составными и примитивными структурами
· Позволяет ограничить типы используемых компонентов
52. Что из перечисленного может быть отнесено к членам класса?
· Вложенный класс
· Метод
· Объект
· Поле
53. Что из перечисленного может быть отнесено к преимуществам шаблона «строитель»?
· В сравнении с фабричным методом придает дополнительную гибкость процессу конструирования объектов
· Изолирует код конструирования объектов
· Позволяет изменять внутреннее представление объекта
· Не требует дополнительной иерархии классов
54. Что из перечисленного может быть отнесено к преимуществам шаблона «хранитель»?
· Позволяет сохранять внутренне состояние объекта
· Упрощает структуру класса-владельца
· Не раскрывает детали реализации класса-владельца
· Позволяет восстанавливать состояние класса-владельца
55. Что из перечисленного может быть отнесено к преимуществам шаблона «прототип»?
· Позволяет специфицировать новые объекты путем изменения значений
· Позволяет сократить иерархию классов
· Позволяет динамически конфигурировать приложение классами
· Значительно уменьшает время, необходимое на создание новых объектов
56. Что из перечисленного может быть отнесено к преимуществам шаблона «стратегия»?
· Позволяет оперировать семейством алгоритмов
· Предотвращает порождение большого числа подклассов
· Сокращает цепочки условных операторов, реализующих сложное поведение системы
· Позволяет динамически выбирать реализацию алгоритма
57. Что из перечисленного может быть отнесено к преимуществам шаблона «посредник»?
· Централизовывает управление
· Обеспечивает слабую связность системы
· Упрощает протоколы взаимодействия между компонентами
· Повышает степень повторной используемости кода
58. Что из перечисленного может быть отнесено к преимуществам шаблона «состояние»?
· Изолирует логику работы от реализации
· Не требует дополнительных имен в адресном пространстве
· Позволяет полностью скрыть информацию о классе-владельце
· Позволяет избегать применения цепочек условных операторов
59. Что из перечисленного может быть отнесено к преимуществам шаблона «фабричный метод»?
· Положительно сказывается на скорости работы
· Позволяет устанавливать связь между параллельными иерархиями классов
· Сокращает количество имен в адресном пространстве
· Позволяет сделать код создания объектов более универсальным
60. Какие задачи позволяет решать ключевое слово final?
· Создание ненаследуемых методов
· Создание абстрактных классов
· Создание непереопределяемых методов
· Создание неизменяемых полей
· Создание классов, которые не могут иметь наследников
61. Что из перечисленного может быть отнесено к преимуществам шаблона «шаблонный метод»?
· Помогает избегать дублирования повторяющихся конструкций
· Позволяет динамически варьировать поведение системы
· Позволяет оптимизировать передачу данных при вызове методов
· Не требует дополнительной иерархии классов
62. Как называется организация, регулирующая развитие UML?
· OMG
· ANSI
· ACM
· NASA
63. Что из перечисленного может быть отнесено к преимуществам шаблона «неизменяемый объект»?
· Позволяет предотвратить ряд ошибок
· Может быть использован в качестве ключа коллекции
· Удобен для многопоточной работы
· Положительно сказывается на скорости работы
Комментарии: Файл содержит сборник вопросов и ответов на тест, состоящий из 63 вопроса. Оценка — отлично. Сдавался в 2022 году. Для корректного прочтения файл следует смотреть на домашнем ПК.
Размер файла: 243,2 Кбайт
Фаил: (.zip)
Некоторые похожие работы:
Спеши, предложение ограничено !
Что бы написать комментарий, вам надо войти в аккаунт, либо зарегистрироваться.
Вход в аккаунт:
Cодержание / Объектно-ориентированное программирование / Ответы на тест «Объектно ориентированное программирование». МФПУ «Синергия»
Клуб студентов «Технарь». Уникальный сайт с дипломами и курсовыми для технарей.
Описание:
Объектно-ориентированное программирование. Синергия. Тест. 2023 год. Перед покупкой убедитесь что вопросы вам подходят.
1. Верно ли, что понятие «суперкласс» является синонимом родительского класса?
2. Верно ли, что понятия «вложенный класс» и «класс-член» являются синонимами?
3. Верно ли, что программист не может управлять сборкой мусора?
4. Верно ли, что концепция MVC включает в себя ровно три структурных составляющих: модель, вид и контроллер?
5. Верно ли, что наиболее общим отношением между классами является отношение зависимости?
6. Верно ли утверждение о том, что Java является декларативным языком
7. Верно ли утверждение о том, что Java является императивным языком программирования?
8. Верно ли, что Java позволяет создавать массив заранее известных величин?
9. Верно ли, что MVC позволяет визуализировать одни и те же данные разными способами без изменения модели?
10. Верно ли, что MVC позволяет подключать к одному виду несколько контроллеров?
11. Верно ли, что для создания деструктора в Java используется блок finalize?
12. Верно ли, что один абстрактный класс не может являться родительским по отношению к другому абстрактному классу?
13. Верно ли, что абстрактный класс не может иметь экземпляров?
14. Верно ли, что абстрактный класс не может содержать реализаций методов?
15. Верно ли, что в активной модели MVC об изменениях данных представление оповещает контроллер?
16. Верно ли, что в пассивной модели MVC об изменениях данных представление оповещает контроллер?
17. Верно ли, что основная цель использование концепции MVC – разграничение логики работы и визуализации?
18. Верно ли, что основная цель использование концепции MVC – упрощение архитектуру приложения?
19. Верно ли, что отношение агрегации может применяться для изображения иерархических отношений между классами?
20. Как расшифровывается аббревиатура JRE?
21. Как расшифровывается аббревиатура JDK?
22. Как расшифровывается аббревиатура JVM?
23. Какая из парадигм программирования является ведующей в языке Java?
24. Какая команда используется для выполнения байт-кода?
25. Какие группы шаблонов проектирования обычно выделяют?
26. Задачи какого рода решают основные шаблоны проектирования?
27. Задачи какого рода решают поведенческие шаблоны проектирования?
28. Задачи какого рода решают порождающие шаблоны проектирования?
29. Задачи какого рода решают структурные шаблоны проектирования?
30. Каким символом на диаграмме классов изображается тот факт, что атрибут имеет область видимости private?
31. Каким символом на диаграмме классов изображается тот факт, что атрибут имеет область видимости protected?
32. Каким символом на диаграмме классов изображается тот факт, что атрибут имеет бесконечную кратность?
33. Каким символом на диаграмме классов изображается тот факт, что атрибут имеет область видимости public?
34. Верно ли то, что отношение композиции является частным случаем отношения агрегации?
35. Верно ли то, что существуют такие классы, которые могут иметь один и только один экземпляр?
36. Какие задачи позволяет решать ключевое слово final?
37. Какие из перечисленных требований должны выполняться для создания шаблона «неизменяемый объект» в Java?
38. Какие из перечисленных утверждений касательно высокоуровневых шаблонов проектирования верны?
39. Какие из перечисленных утверждений касательно низкоуровневых шаблонов проектирования верны?
40. Какие из предлагаемых утверждений верны?
41. Какие типы связей используют в UML?
42. Какие типы сущностей выделяют в UML?
43. Каково основное назначение статического импорта?
44. Какое из перечисленных утверждений верно?
45. Какое ключевое слово может быть использовано для обращения экземпляра класса к самому себе?
46. Какое количество секций может содержать блок описания интерфейса на UML-диаграмме классов?
47. Какое количество секций может содержать блок описания класса на UML-диаграмме классов?
48. Как расшифровывается аббревиатура UML?
49. Что из перечисленного может быть отнесено к преимуществам шаблона «стратегия»?
50. Что из перечисленного может быть отнесено к преимуществам шаблона «строитель»?
51. Что из перечисленного может быть отнесено к преимуществам шаблона «фабричный метод»?
52. Что из перечисленного может быть отнесено к преимуществам шаблона «фасад»?
53. Каким образом будет выглядеть команда для компиляции класса test, описанного в файле test.java?
54. Сколько байт в памяти ЭВМ занимается одна переменная типа char?
55. Как называется один из фундаментальных механизмов объектно-ориентированного программирования, позволяющий классу ограничивать доступ к своим членам?
56. Как называется один из фундаментальных механизмов объектно-ориентированного программирования, позволяющий одному классу расширять функциональность другого, заимствуя при этом поля и методы?
57. Как называется один из фундаментальных механизмов объектно-ориентированного программирования, позволяющий элементам с одинаковой спецификацией иметь различную реализацию?
58. Как называется специализированный метод класса, предназначенный для создания нового экземпляра?
59. Как называется специализированный метод класса, предназначенный для уничтожения существующего экземпляра?
60. Какое ключевое слово используется для указания класса-родителя?
61. Какое ключевое слово используется для указания того, что класс реализует интерфейс?
62. Какое название получил механизм, позволяющий JVM работать с примитивными типами данных как с объектами?
63. Какой вид будет иметь инструкция, добавляющая в область видимости описываемого класса все классы из пакета test?
64. Каким образом будет выглядеть инструкция, указывающая на принадлежность описываемого класса к пакету test, который в свою очередь является под пакетом класса bigtest?
65. Какой вид будет иметь инструкция, добавляющая в область видимости описываемого класса класс test из пакета test?
66. Какой вид будет иметь инструкция, указывающая на принадлежность описываемого класса к пакету test?
67. С помощью какой команды может быть создан вектор с именем test из элементов типа TestEl?
68. С помощью какой команды может быть создан массив с именем test из десяти элементов типа int?
69. Как будет выглядеть команда для запуска класса Test, готовый байт код которого
70. Как называется организация, регулирующая развитие UML?
71. Что из перечисленного может быть отнесено к членам класса?
72. Что из перечисленного может быть отнесено к преимуществам шаблона «шаблонный метод»?
73. Что из перечисленного может быть отнесено к недостаткам шаблона «отложенная инициализация»?
74. Что из перечисленного может быть отнесено к преимуществам шаблона «адаптер»?
75. Что из перечисленного может быть отнесено к преимуществам шаблона «делегирование»?
76. Что из перечисленного может быть отнесено к преимуществам шаблона «декоратор»?
77. Что из перечисленного может быть отнесено к преимуществам шаблона «заместитель»?
78. Что из перечисленного может быть отнесено к преимуществам шаблона «итератор»?
79. Что из перечисленного может быть отнесено к преимуществам шаблона «команда»?
80. Что из перечисленного может быть отнесено к преимуществам шаблона «компоновщик»?
81. Что из перечисленного может быть отнесено к членам класса?
82. Что из перечисленного может быть отнесено к преимуществам шаблона «наблюдатель»?
83. Что из перечисленного может быть отнесено к преимуществам шаблона «неизменяемый объект»?
84. Что из перечисленного может быть отнесено к преимуществам шаблона «хранитель»?
85. Что из перечисленного может быть отнесено к преимуществам шаблона «цепочка ответственности»?
86. Что из перечисленного может быть отнесено к преимуществам шаблона «одиночка»?
87. Что из перечисленного может быть отнесено к преимуществам шаблона «посредник»?
88. Что из перечисленного может быть отнесено к преимуществам шаблона «прототип»?
89. Что из перечисленного может быть отнесено к преимуществам шаблона «состояние»?
Комментарии: Объектно-ориентированное программирование. Синергия. Тест. 2023 год. Перед покупкой убедитесь что вопросы вам подходят.
Размер файла: 384,8 Кбайт
Фаил: (.pdf)
NSSimpleApps / answers.md
Цепочка ответсвенности, что происходит с методом после того как он не нашелся в объекте класса, которому его вызвали (в сторону forwardInvocation:)?
- В категории объявляются дополнительные методы. В расширении добавляются методы и поля.
- Да.
Class c = objc_allocateClassPair([NSObject class], "Person", 0); class_addIvar(c, "firstName", sizeof(id), log2(sizeof(id)), @encode(id)); Ivar firstNameIvar = class_getInstanceVariable(c, "firstName");
- Категория используется, чтобы не плодить классы, только добавить нужный метод. Наследование используется для переопределения существующих методов.
- Они принадлежат к различным шаблонам проектирования.
- Первый неизменяемый, второй изменяемый.
- NSSet хранит только уникальные объекты.
- NSArray : добавление, удаление. NSSet использует hashvalues для поиска объекта, является неупорядоченным.
- Неформальный протокол — категория над NSObject , которая заставляет все объекты адаптировать этот протокол. Формальный — обычный протокол @protocol
- Да. @public , @private @protected . Фактически до любого свойства можно доступиться через KVC или runtime
- Итерация (цикл) по коллекциям ( NSArray , NSDictionary ): for Type *item in Collection <>
Model-View-Controller в .Net
В наше время сложно найти разработчика, который не слышал бы о паттерне под названием Model-View-Controller или сокращенно MVC, что вообщем не удивительно, с задачей отделения данных от их представления сталкиваешься практически на каждом проекте. Однако, как ни странно, столь же сложно найти разработчика, который действительно четко себе представляет, что такое на самом деле паттерн MVC и как его можно реализовать в конкретной ситуации. Подобное неведение явилось следствием того, что по историческим причинам данной аббревиатурой принято называть не один единственный паттерн, а целое семейство паттернов, призванное отделять представление от модели. Произошло это в силу разных обстоятельств. Отчасти из-за того что MVC не просто паттерн, а довольно объемное архитектурное решение, в котором каждый новый разработчик видел что-то свое и ставя во главу угла особенности своего проекта, реализовывал его по своему. Отчасти же из-за возраста данного паттерна, во времена его изобретения и сами приложения, и графические интерфейсы были существенно беднее чем в наше время, с тех пор они сильно эволюционировали и вместе с ними изменялся и сам паттерн. Данная статья посвящена также одному из паттернов входящих в это семейство, причинам его появления, особенностям применения, преимуществам и недостаткам, а так же описанию сопутствующих паттернов.
«Оригинальный» MVC
Несмотря на то, что, как уже говорилось, под аббревиатурой MVC обычно понимают целое семейство паттернов, можно выделить первоначальный вариант данного архитектурного решения. На данный момент, применение MVC в оригинальном виде вряд ли будет оправдано, по разным причинам, однако эволюцию паттерна лучше проследить с самого начала.
Впервые паттерн MVC появился в языке SmallTalk в конце семидесятых. Собственно задача была хорошо всем знакомая, надо было придумать архитектурное решение, которое позволяло бы манипулировать графическими представлениями данных некоего приложения, таким образом, чтобы изменение Представления этих данных не влияло на бизнес-логику и данные ( Модель ) приложения, а так же, чтобы была возможность иметь несколько Представлений для одной Модели . Таким решением и стал паттерн MVC, идея которого родилась в недрах Xerox PARK, и получила свое первое публичное упоминание в документации к SmallTalk’80. В классическом варианте, MVC состоит из трех частей, которые и дали ему название.
Model (Модель)
Под Моделью , обычно понимается часть содержащая в себе функциональную логику приложения, иными словами то, что мы обычно называем «Business Layer», «Бизнес-слой» или «Слой бизнес логики». Как именно организован этот слой, по большому счету не важно, однако есть ряд ключевых моментов, на которых мы остановимся позднее. Основная цель паттерна — сделать так, чтобы Модель была полностью независима от остальных частей и практически ничего не знала об их существовании, что позволило бы менять и Контроллер и Представление модели, не трогая саму Модель и даже позволить функционирование нескольких экземпляров Представлений и Контроллеров с одной Моделью одновременно. Вследствии чего, Модель ни при каких условиях не может содержать ссылок на объекты Представления или Контроллера .
Обычно различают несколько типов паттернов в зависимости от роли модели.
Passive Model (пассивная модель) — Модель не имеет вообще никаких способов воздействовать на Представление или Контроллер и только используется ими в качестве источника данных для отображения. Все изменения модели отслеживаются Контроллером и он же отвечает за перерисовку Представления , если это необходимо.
Active Model (активная модель) — Модель имеет возможность оповестить Представление о том, что в ней произошли некие изменения, и Представление может эти изменения отобразить. Как правило, механизм оповещения реализуется на основе паттерна Observer (обозреватель), Модель просто бросает сообщение, а Представления , которые заинтересованы в оповещении, подписываются на эти сообщения, что позволяет сохранить независимость Модели как от Контроллера так и от Представления, не нарушая тем самым основного свойства паттерна. Классической реализацией паттерна MVC принято считать версию именно с активной Моделью .
СОВЕТ
Паттерн Observer (Обозреватель), известен так же под именем Publish/Subscribe (Публикатор/Подписчик), предназначен для организации наблюдения за состоянием объекта. Суть паттерна в том, что несколько объектов, называемых «обозревателями» или «слушателями» (listeners), регистрируются, сами или с чьей-либо помощью, в качестве обработчиков события (event), которое инициируется наблюдаемым объектом – «субъектом» (Subject) при изменении своего состояния. Таким образом достигается независимость «Субъекта» от «Обозревателей».
View (Представление)
В обязанности Представления входит отображение данных полученных от Модели . Обычно Представление имеет свободный доступ к Модели и может брать из нее данные, однако это доступ только на чтение, ничего менять в Модели или даже просто вызывать методы приводящие к изменению ее внутреннего состояния, Представлению позволять нельзя. В случае активной Модели , Представление может подписаться на события изменения Модели и перерисовываться, забрав измененные данные, при получении соответствующего оповещения. Для взаимодействия с Контроллером , представление, как правило, реализует некий интерфейс, известный Контроллеру , что позволяет менять представления независимо и иметь несколько представлений на Контроллер . Вообще, подмена или изменение Представления самая часто встречающаяся задача, по сути это и есть та причина по которой придумывают различные паттерны разделения Модели и Представления .
Controller (Контроллер)
В задачи Контроллера входит реакция на внешние раздражители и изменение Модели и/или Представления в соответствии с заложенной в него логикой. Один Контроллер может работать с несколькими Представлениями , в зависимости от ситуации, взаимодействуя с ними через некий заранее известный интерфейс, который эти Представления реализуют. Важный нюанс, в классической версии MVC Контроллер не занимается передачей данных из Модели в Представление и не является медиатором (Mediator) между Моделью и Представлениями .
ПРИМЕЧАНИЕ
Стоит упомянуть, что MVC ни коим образом не определяет каким именно способом Модель взаимодействует с данными и как реализован уровень доступа к данным – это лежит вне зоны ответственности данного паттерна.
Таким образом, типичная схема взаимодействия компонентов паттерна выглядит примерно так: Контроллер перехватывает событие извне и в соответствии с заложенной в него логикой, реагирует на это событие изменяя Mодель , посредством вызова соответствующего метода Модели . После изменения Модель бросает событие о том что она изменилась, и все подписанные на это события Представления , получив его, обращаются к Модели за обновленными данными, после чего их и отображают.
При этом еще в описании оригинального паттерна упоминалось, что выделение отдельного Контроллера не так важно как отделение Представления от Модели и Контроллер вполне может быть интегрирован в Представление , тем более что в классическом варианте MVC логики в Контроллере не очень много, впрочем к этому мы еще вернемся.
Следующим этапом развития MVC стал паттерн Document-View, хорошо известный по таким библиотекам как Turbo Vision (Pascal 6.0, ох ностальгия, Microsoft Foundation Class Library и многих других, вплоть до WinForms.
ПРИМЕЧАНИЕ
Строго говоря, утверждать, что эти библиотеки реализуют именно Document-View было бы не совсем верно, в конце-концов это всего лишь библиотеки и использовать их можно по разному, вернее было бы сказать, что эти библиотеки склоняют к использованию MVC именно в таком виде, как примерами из документации, так и собственной архитектурой.
В этой версии MVC Контроллер интегрирован в Представление , что ни в коей мере не является нарушением основной идеи паттерна. Сделано это было по многим причинам, прежде всего, отделение Контроллера от Представления , действительно не самая ключевая часть паттерна. Другой причиной являлось появление, графических оболочек встроеных в ОС, что позволяло не рисовать графические элементы (контролы) пользовательского интерфейса под каждый проект, а использовать готовые, предоставляемые платформой посредством соответствующего API, но дело в том, что в этих оболочках функции Контроллера уже были интегрированы в контролы (которые и являются Представлениями или же частями оного). Свою роль сыграло и появление визуальных графических оболочек встроеных в среду программирования (так называемые widget-based среды пользовательского интерфейса), поскольку код сгенеренный этими оболочками, естественно, использовал готовые графические элементы платформы и, как следствие, опять-таки провоцировал разработку в стиле Document-View. WinForms, в купе с Visual Studio, так же являются примером такой среды.
У той же Microsoft, которая выкладывает довольно много статей по архитектурным решениям в свободный доступ, есть несколько публикаций и по MVC, и там можно легко заметить, что все примеры чистого MVC даются не на основе WinForms приложений, а на примере ASP.NET, где, в отличии от WinForms, есть относительно четкое разделение между Контроллером и Представлением , про WinForms же есть только упоминание о том, что, как правило, в подобного рода приложениях Контроллер интегрирован в Представление .
Недостатки MVC и Document-View
В целом MVC и Document-View, как его логическое продолжение вполне адекватные паттерны для ряда задач, и с успехом применяются в большем количестве проектов, но в то же время обладают и рядом недостатков.
Прежде всего, чистый MVC плохо подходит для сред типа WinForms, поскольку, как уже говорилось выше, код, который порождают среды и библиотеки провоцирует интегрировать Контроллер в Представление . Получающийся в результате вариант паттерна в виде Document-View, в принципе, вполне приемлемое решение, однако далеко не всегда. Дело в том, что логика Контроллера , на самом деле, практически не зависит от типа Представления и сама по себе довольно неплохо поддается тестированию. А встраивание этой логики в Представление , в случае разных типов Представлений , приводит к дублированию кода и практически исключает возможность внятного тестирования этой логики, так как тестирование пользовательского интерфейса – это отдельная головная боль. Да и в целом, реализация логики контроллера вместе с представлением порождает довольно кашеобразную конструкцию из смеси автогенеренного и ручного кода Представления и кода логики Контроллера , который довольно сложно поддерживать. С появлением FW 2.0 и Partial-классов стало несколько легче, но проблема все равно актуальна.
Если же попытаться выделить Контроллер «в лоб», то можно нарваться на следующие неприятности.
В оригинальном паттерне именно контроллер должен реагировать на внешние события, однако в коде порожденном дизайнером Visual Studio все обработчики уже встроены в Представление. Приходится либо уходить от автогенеренного кода и готового дизайнера форм, что вряд ли можно назвать адекватным решением, либо как-то пытаться адаптировать сгенерированный дизайнером код под вынесение обработчика событий во внешний контроллер.
Далее, выделя контроллер в его классическом варианте, можно столкнуться с недостатком связанным с особенностью роли Модели в классическом MVC. Как уже говорилось, MVC – это не просто паттерн, а набор паттернов, и Модель , в классическом MVC, на самом деле является медиатором (Mediator) между Контроллером/Представлением и реальной моделью домена (Domain Model) приложения (как это отражено на схеме).
СОВЕТ
Паттерн Mediator (Медиатор), заключается в реализации единого объекта, который скрывает взаимодействие группы объектов между собой. Предназначен для уменьшения связности и сложности системы, за счет того, что с группой объектов можно работать как с единым целым.
В обязанности Медиатора входит транслировать вызовы Контроллера в нужные модели приложения и реализовать механизм оповещения Представлений , как правило посредством паттерна Обозреватель (Observer), о том, что нижележащая модель приложения изменилась. Таким образом, Модель должна обладать набором методов реализующих логику работы с пользовательским интерфейсом, однако сама Модель не может влиять напрямую на этот самый интерфейс (представления), в противном случае это убило бы саму идею паттерна, что приводит к необходимости реализации в Представлении логики обработки событий и, как следствие, «утолщению» Представления . Плюс к этому, в некоторых случаях хотелось бы дать пользователю возможность непосредственно влиять на Представление , без привлечения событийного механизма. Например, изменение цвета в некоторых Представлениях в классическом MVC выглядело бы так: в Контроллер попадает событие изменения цвета с кодом цвета, Контроллер вызывает соответствующий метод в Модели , в котором Модель выставляет нужный цвет и бросает событие о том, что в ней произошли изменения, затем данное событие перехватывается Представлениями и Представления перерисовываются, самостоятельно забрав у Модели новый цвет. Сам Контроллер не может отдать команду перерисоваться с нужным цветом, так как не умеет хранить состояние цвета и не знает каким Представлениям нужно передавать эту команду.
Таким образом нам нужна модификация паттерна которая, с учетом упомянутых недостатков, позволяла бы следующее:
- Умела эффективно отделять модель от ее представлений.
- Позволяла пользоваться дизайнером форм и имеющимися библиотеками, без ограничений.
- Позволяла тестировать логику Контроллера независимо от Представления и вообще, сводила бы логику Представления к минимуму.
- Позволяла бы избегать лишних обращений к Модели .
Одним из возможных решений, отвечающим всем вышеприведенным требованиям, и является паттерн Model-View-Presenter (MVP).
Model-View-Presenter
Паттерн Model-View-Presenter, является очередной модификацией MVC. Если смотреть просто на схему, то визуально отличить его от MVC довольно сложно, поэтому лучше всего иллюстрировать его реализацию на кусочке реального кода. Код, конечно, реальный весьма относительно и довольно примитивен, однако надеюсь, вполне достаточнен для иллюстрации паттерна — мы попробуем реализовать программу, переводящую градусы цельсия в фаренгейты и наоборот, ну и, естественно, визуально это дело отображающую.
Model
Если бы мы разрабатывали наше приложение в привычном стиле, навязываемом WinForms, то скорее всего начали бы с набрасывания формочек, однако в данном случае мы зайдем с другой стороны и начнем с реализации Модели . И так, наша Модель должна уметь принимать данные температуры как в цельсиях так и в фаренгейтах и пересчитывать их в других величинах. Типичная Модель для данной задачи могла бы выглядеть следующим образом:
public class Model < privatedouble _valueFahrenheit = 32; privatedouble _valueCelsius = 0; /// /// Градусы в шкале Фаренгейта/// publicdouble valueFahrenheit < get < return _valueFahrenheit; > set < _valueFahrenheit = value; _valueCelsius = (_valueFahrenheit - 32) * 5 / 9; >> /// /// Градусы в шкале Цельсия/// publicdouble valueCelsius < get < return _valueCelsius; > set < _valueCelsius = value; _valueFahrenheit = _valueCelsius * 9 / 5 + 32; >> >
Presenter
Следующим этапом будет реализация Presenter -а, эта сущность заменяет Контроллер в классическом MVC — она делает все тоже самое, что и Контроллер , плюс кое-что еще. Более подробно о его функциях мы поговорим позже.
Presenter может иметь прямую ссылку на экземпляр Модели . В то же время Presenter должен иметь ссылку и на экземпляр или даже экземпляры Представления , которые будут отображать данные Модели . Однако здесь, в отличие от случая с Моделью , создание конкретного экземпляра конкретного класса Представления , может обернуться большими неудобствами. При наличии тесной связи между Presenter-ом и Представлением будет сложно реализовать замену Представлений и использование нескольких Представлений для одного Presenter-а , к тому же, это затруднит независимое тестирование Presenter-а. Да и в целом, наличие такой связи может привести к неправильной работе Presenter-а при изменении Представления , что совсем не хорошо.
Решить проблему зависимости Presenter-а от Представления можно с помощью паттерна Inversion of Control (он же Dependency Injection по Фаулеру) . Для этого мы создаем интерфейс Представления через который и будет осуществляться все взаимодействие с Представлениями .
СОВЕТ
Inversion of Control (IoC), это даже не паттерн, а архитектурный принцип, который используется для уменьшения связности между объектами. Суть его довольно проста. Допустим объект x (класс X) вызывает некий метод объекта y (класс Y), в этом случае считается, что X зависит от Y. Данная зависимость может быть «перевернута» путем введения третьего класса I, называемого интерфейсным классом, который содержит в себе все методы, которые x вызывает у объекта y, при этом Y должен реализовывать интерфейс I. После подобного преобразования X и Y зависят от I, но не зависят друг от друга, более того, если ранее X так же транзитивно зависил от всех классов от которых зависит Y, то теперь и эта зависимость оказалась разорвана.
Интерфейс Представления , в нашем случае, будет состоять из свойств для вывода посчитанных значений градусов цельсия и фаренгейта, ввода новых данных и событий оповещающих Presenter, что данные введены.
public interface IView < /// /// Вывод градусов Фаренгейта/// void SetFarenheit(double value); /// /// Вывод градусов Цельсия/// void SetCelsius(double value); /// /// Ввод нового значения градусов/// double InputDegree < get; >/// /// Событие ввода значения по Фаренгейту/// event EventHandler SetFarenheit; /// /// Событие ввода значения по цельсию/// event EventHandler SetCelsius; >
После того, как интерфейс готов, надо придумать как подпихнуть экземпляр интерфейса в Presenter. В данном случае, для простой задачи, можно сделать это через конструктор, в более сложных ситуациях Presenter может получать ссылку на конкретный экземпляр через специальную фабрику представлений или даже сам являться фабрикой, порождающий необходимые Представления в зависимости от ситуации.
СОВЕТ
Паттерн Factory Method (фабричный метод), как и другие «строительные» паттерны, предназначен для создания объекта без указания конкретного класса реализующего этот объект. В данном случае это делается путем объявления в самом классе только публичного интерфейса для создания объекта, само же создание делегируется классам-наследникам.
Наличие интерфейса так же позволяет уже на этом этапе полностью завершить разработку Presenter-а и заняться его тестированием, несмотря на то, что конкретные Представления еще не готовы и ни один контрол еще не брошен на форму. ( И так, Presenter может выглядеть примерно следующим образом:
public class Presenter < private Model _model = new Model(); private IView _view; ////// В конструтор передается конкретный экземпляр представления /// и происходит подписка на все нужные события. /// public Presenter(IView view) < _view = view; _view.SetCelsius += new EventHandler(OnSetCelsius); _view.SetFarenheit += new EventHandler(OnSetFarenheit); RefreshView(); > /// /// Обработка события, установка нового значения градусов по Фаренгейту/// privatevoid OnSetFarenheit(object sender, EventArgs e) < _model.valueFahrenheit = _view.InputDegree; RefreshView(); >/// /// Обработка события, установка нового значения градусов Цельсия/// privatevoid OnSetCelsius(object sender, EventArgs e) < _model.valueCelsius = _view.InputDegree; RefreshView(); >/// /// Обновление Представления новыми значениями модели./// По сути Binding (привязка) значений модели к Представлению. /// privatevoid RefreshView() < _view.SetCelsius(_model.valueCelsius); _view.SetFarenheit(_model.valueFahrenheit); >>
В реальных приложениях это, как правило, гораздо более сложный класс, но об этом мы поговорим позже.
View
В данном случае реализовать интерфейс можно в классе реализующем форму, причем сделать это можно в отдельном проекте, вдруг потом захочется реализовать и web-интерфейс? ( Разработка конкретного Представления совсем тривиальна, форма представления наследуется от созданного нами ранее интерфейса, при этом реализация свойств интерфейса примитивна – по сути это просто перекладывание значений из интерфейса в контролы и наоборот.
public partial class FormView : Form, IView < #region Реализация IView /// /// Вывод градусов Фаренгейта/// publicdouble Farenheit < set < _farenheitBox.Text = value.ToString("N2"); > > /// /// Вывод градусов Цельсия/// publicdouble Celsius < set < _celsiusBox.Text = value.ToString("N2"); > > /// /// Ввод нового значения градусов/// publicdouble InputDegree < get < return Convert.ToDouble(_inputBox.Text); > > #endregion/// /// Обработка событий тоже примитивна, они просто пробрасываются/// в соответствующие события Presenter-а/// privatevoid _celsiusButton_Click(object sender, EventArgs e) < if (SetCelsius != null) SetCelsius(this, EventArgs.Empty); > privatevoid _farenheitButton_Click(object sender, EventArgs e) < if (SetFarenheit != null) SetFarenheit(this, EventArgs.Empty); > >
Ну и, наконец, завершающий штрих, необходимо создать экземпляр Представления , подпихнуть его в Presenter и запустить всю эту конструкцию на выполнение.
static class Program < [STAThread] staticvoid Main() < FormView view = new FormView(); Presenter presenter = new Presenter(view); Application.Run(view); > >
Вот собственно и все, паттерн MVP в своем простейшем варианте перед вами, самое время его обсудить.
Почему интерфейс?
Хотелось бы более подробно остановиться на интерфейсе IView, что дает его использование, и почему бы не заменить его на базовый класс, с некоторой примитивной реализацией.
Строго говоря, сам паттерн вовсе не обязывает использовать для представления именно интерфейс, но использование здесь именно интерфейса, на мой взгляд, дает ряд преимуществ. Прежде всего, как и завещано создателями упоминавшегося принципа IoC, подобный подход уменьшает зависимость между классами. Замена интерфейса на некоторую базовую реализацию привела бы к тому, что изменение базовой реализации могло бы нарушить правильную работу использующего эту реализацию класса, в данном случае Presenter-а.
Помимо этого, использование интерфейса дает возможность делать Представление из объектов находящихся на любом уровне уже существующих иерархий, предоставляемых готовыми библиотеками. Например, в вышеприведенном случае, вполне можно было бы сделать базовую реализацию унаследовав ее от System.Windows.Forms , но дело в том, что конкретное Представление не обязательно может являться формой, с тем же успехом это может быть и контрол и даже произвольный класс, агрегирующий в себе графические элементы, а наследование от System.Windows.Forms жестко впишет базовый класс Представления в уже имеющуюся иерархию, и лишит подобной гибкости. Более того, с применением интерфейса Представление вообще может быть реализовано не в Win, а в Web-интерфейсе, реализовав, например, интерфейс IView от наследника System.Web.UI.Page. Очевидно, применение базовой реализации вместо интерфейса, как минимум, серьезно затруднило бы такой вариант использования Представлений .
Ну и, наконец, одной из особенностей данного паттерна является, так называемая, «скромность» Представления (humble view) по Фаулеру, то есть, в Представлении содержится вообще самый минимум логики, в некоторых источниках это так же называют «ультра тонкое» представление. Вследствии этого реализация интерфейса IView, как правило, крайне примитивна, чего собственно и добивались, декларируя необходимость вынесения максимального количества логики из Представления в Presenter.
Отличия от MVC
Чем же данный паттерн отличается от «классического» MVC и почему Controller назвали Presenter-ом?
Прежде всего, можно заметить, что, количество связей между сущностями уменьшилось, как правило, в MVP Модель не общается с Представлением даже опосредовано, через механизм оповещений, но это не обязательное условие, более глубокие отличия лежат как раз в области Presenter-а.
Как уже упоминалось выше, в MVC Модель , на самом деле, является медиатором, между Контроллером/Представлением и реальной моделью домена (Domain Model) приложения. В MVP-же, что видно на схеме, такого медиатора нет и его функции берет на себя Presenter, таким образом Presenter, в отличие от Контроллера , общается непосредственно с моделью приложения, а не с неким промежуточным звеном. Это позволяет, в случае необходимости, общаться Presenter-у с Представлениями , минуя Модель приложения и событийный механизм с этим связанный, так как Presenter в отличии от Контроллера , обладает необходимыми знаниями о Представлениях, а так же удаляет лишнюю логику обработки событий от Модели из Представления .
Отдельно стоит упомянуть совместимость с существующими оболочками и средами, что являлось одним из требований к MVP. В оригинальном MVC интерфейсом ко внешним событиям является Контроллер , однако большинство существующих библиотек и сред интегрируют эту функцию в Представление , провоцируя тем самым разработку в стиле Document-View. Этот момент обходится в MVP за счет того, что все нужные Presenter-у события описываются в интерфейсе Представления , и все необходимые события возниающие в Представлении просто пробрасываются в Presenter, что позволяет вынести из Представления логику их обработки.
Вследствии этого, как уже так же упоминалось, в отличии от MVC, Представление в MVP является «скромным» или «ультра-тонким» и практически не содержит логики независимой от конкретного Представления . Эту особенность, помимо всего прочего, очень любят маньяки от тестирования типа того же Фаулера, любители TDD, продвигатели XP и прочих Agile методологий, поскольку «скромные» представления сводят код не покрытый модульными тестами к минимуму.
Иными словами, если в случае MVC Контроллер играет довольно примитивную роль вызывальщика соответствующих методов Модели при реакции на событие, то Presenter в MVP уже берет на себя ведущие функции по управлению Моделями и Представлениями . Боюсь только, что данная особенность не нашла отражения в приведенном примере.
Заключение
Выше была описана, если можно так выразиться, базовая версия паттерна, однако внутри генеральной линии возможно несколько модификаций и вариантов применения.
Например, упомянутый здесь уже неоднократно Фаулер, выделяет аж три возможных модификации MVP, это Presentation Model, Supervising Controller и Passive View. Все они отличаются исключительно способом взаимодействия Presenter-а и Представления , а точнее способами передачи данных представлению. Если мы себе позволяем передавать в Представление бизнес-объекты, вместо примитивных типов, то это Presentation Model, если же позволили Представлению знать о наличии модели и самому забирать из нее данные, то это Supervising Controller, ну а самый простой случай, когда логика Представления действительно минимальна то с нами Passive View. В каждом конкретном случае выбор между этими тремя модификациями паттерна зависит от того, на сколько умную автоматическую привязку бизнес объектов к интерфейсу Представления вы можете использовать и какая степень покрытия тестами логики Presenter-а вас устроит. Ну и, само собой, от сложности бизнес-объектов и интерфейсов.
Для реальных ситуаций, которые, как правило, несколько сложнее приведенного примера, существуют модификации паттерна позволяющие выстроить определенную иерархию. Выделяют два варианта таких иерархических паттернов – это Hierarchical Model-View-Controller (HMVC) и Presentation-Abstraction-Control (PAC), который пришел из мира Java. Отличие заключается в том, что HMVC позволяет выстраивать независимые иерархии, отдельно для Представлений , отдельно для Контроллера /Presenter-а, ну и само-собой для Модели, с прямыми ссылками между собой, то есть, например, Представление может ссылаться непосредственно на дочернее Представление . В свою очередь PAC, более строгий паттерн, и предписывает иметь связи между собой только Контроллерам , другие сущности доступны извне исключительно через свой Контроллер .
В целом, применение MVP, вместо уже ставшего традиционным Document-View, с одной стороны, несколько увеличивает объем ручного кодирования, однако с другой, позволяет покрыть большую часть логики тестами, уменьшает связность между компонентами и может служить основой для реализации механизма «скинов» (оболочек, шкурок) приложения, вплоть до того, что для одного и того же «движка», можно иметь как Win, так и Web «шкурку».
Что почитать
- Wikipedia: Model-View-Controller (http://en.wikipedia.org/wiki/Model_view_controller)
- Twisting The Triad (http://www.object-arts.com/Papers/TwistingTheTriad.PDF) by Andy Bower, Blair McGlashan
- GUI Architectures (http://www.martinfowler.com/eaaDev/uiArchs.html) by Martin Fowler
- Microsoft Journal: Model-View-Presenter (http://msdn.microsoft.com/msdnmag/issues/06/08/DesignPatterns/default.aspx) by Jean-Paul Boodhoo
- Supervising Controller (http://www.martinfowler.com/eaaDev/SupervisingPresenter.html) by Martin Fowler
- Passive View (http://www.martinfowler.com/eaaDev/PassiveScreen.html) by Martin Fowler
- Presentation Model (http://www.martinfowler.com/eaaDev/PresentationModel.html) by Martin Fowler
Эта статья опубликована в журнале RSDN Magazine #2-2006. Информацию о журнале можно найти здесь