Проблемы понимания mvc в asp.net mvc и не только

Тестирование сигналов

Одна из ключевых особенностей Qt – это объектная связь на основе сигналов и слотов, которая по сути является системой, основанной на событиях.

Для ее тестирования Qt Test предлагает класс под названием , который представляет собой на стероидах, который может перехватывать и записывать сигналы.

Как и предполагалось во введении, класс выдает два сигнала:

  • – выдается после нажатия кнопки CONCAT и объединения входного текста.
  • – выдается после нажатия кнопки CANCEL и очистки всего текста.

В следующем тесте код будет имитировать нажатие двух кнопок и проверять выдаваемые сигналы.

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

Вторая часть имитирует нажатие кнопки CONCAT, а затем проверяет, записан ли сигнал . Проверить это можно, просто определив, сколько элементов содержит соответствующий объект (). Затем последний проверяет, соответствует ли параметр, полученный из сигнала, строке результата.

Последняя часть функции тестирования имитирует нажатие кнопки CANCEL и проверяет, получен ли сигнал , и что он не содержит никаких параметров.

В этом примере для простоты я проверил 2 сигнала в одном тесте, но было бы лучше держать эти вещи изолированными в двух разных тестах. Помните об этом при написании реальных юнит-тестов.

Как пишутся тесты

Составление тестов начинается со сбора списка требований к тестируемому коду. Затем для каждого требования пишется тестовый сценарий, который проверяет, что оно выполняется. Сценарии бывают позитивными — когда мы передаем корректные данные и ждем успешный результат, и негативными — когда мы передаем неправильные данные и ждем сообщение об ошибке.

Вот пример сбора требований. Допустим, что у нас есть функция , которая обрезает строку, если она длиннее N символов. Каким требованиям она должна соответствовать?

  • если передать ей строку из 5 символов и = 10, функция должна вернуть строку без изменений
  • если передать ей строку из 11 символов и = 5, то функция должна обрезать строку до

Вот более сложный пример. Допустим, у нас есть система бронирования номеров в отеле, и мы хотим написать интеграционные тесты для класса , который отвечает за создание броней. Тут список требований будет другой:

  • если передать корректные дату заезда, дату выезда, количество человек и в наличии есть свободные номера, то должна создаться бронь
  • если дата выезда раньше или совпадает с датой заезда, должна вернуться ошибка
  • если количество человек меньше или равно нулю, должна вернуться ошибка
  • если свободных номеров на выбранные даты нет, должна вернуться ошибка

На каждое требование мы пишем отдельный тест — это позволит при ошибке понять, что именно сломалось. Тесты обычно пишут в стиле Arrange, Act, Assert. Мы сначала подготавливаем и настраиваем нужные компоненты (Arrange), выполняем действие (Act) и проверяем результат (Assert).

class TruncateTest extends \PHPUnit\Framework\TestCase
{
    public function testShortStringRemainsAsIs()
    {
        // Act: вызываем функцию
        $result = truncate("hello", 10);
        // Assert: проверяем, что возвращенный результат совпадает с ожидаемым
        $this->assertEquals("hello", $result);
    }

    public function testLongStringIsTruncated()
    {
        $result = truncate("hello world", 5);
        $this->assertEquals("hello…", $result);
    }
}

Метод из PhpUnit проверяет, что фактический результат совпадает с ожидаемым, и выдает ошибку, если это не так. В PhpUnit много assert-функций на все случаи жизни.

Модульное тестирование графического интерфейса пользователя с помощью Qt Test

В данном руководстве я расскажу о модульном тестировании GUI с помощью Qt Test, фреймворка Qt для модульного тестирования кода на C++. В частности, я расскажу, как написать базовый юнит-тест для класса виджета, как имитировать события мыши и клавиатуры и как для графических интерфейсов писать тесты, управляемые данными.

Это третий пост из серии, посвященной Qt Test. Посты этой серии:

  • Модульное тестирование кода на C++ с помощью Qt Test. Часть1. Введение
  • Модульное тестирование кода на C++ с помощью Qt Test. Часть 2. Расширенное тестирование
  • Модульное тестирование GUI (графического интерфейса пользователя) с помощью Qt Test. Часть 1. Введение
  • Модульное тестирование GUI (графического интерфейса пользователя) с помощью Qt Test. Часть 2. Расширенное тестирование

Рекомендую прочитать предыдущие посты этой серии, чтобы полностью понять новые концепции, которые я представлю здесь.

Исходный код

Полный исходный код этого руководства доступен на GitHub.

Полная структура проекта включает 3 подпроекта:

  • – динамическая библиотека, содержащая класс виджета;
  • – пример приложения, использующего виджет ;
  • – юнит-тест .

Чтобы попробовать этот пример в работе, загрузите в Qt Creator верхний проект с поддиректориями под названием .

Имейте в виду, что по умолчанию при запуске проекта запускается пример приложения. Для запуска модульных тестов вы можете изменить активную конфигурацию запуска, использовать панель Тесты или использовать меню Инструменты (Tools) → Тесты (Tests) → Запустить все (Run All Tests).

Справочная информация

Чтобы узнать больше о Qt Test, вы можете ознакомиться с последней документацией по пространству имен и классу .

Преимущества и недостатки

1. Преимущества

  • Низкая связь, Представления могут быть изменены и изменены независимо от модели. Модель представления может быть привязана к различным «представлениям». При изменении представления модель не может изменяться, а при изменении модели вид также может изменяться.
  • Улучшить ремонтопригодность, Решить проблему ручной синхронизации MVP большого количества видов и моделей и предоставить механизм двусторонней привязки. Повысить удобство сопровождения кода.
  • Упростить тестирование, Поскольку логика синхронизации выполняется Binder, и представление изменяется одновременно с моделью, вам нужно только убедиться в правильности модели и представления. Значительно уменьшите тест для просмотра синхронного обновления.

2. Недостатки

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

6. Резюме

Разработка различных режимов MV + X,По сути, это управление моделью и видом экономичным и экономичным способом., В MVC модель и представление не полностью разделены, в результате чего код Activity будет раздутым. В MVP Presenter используется для передачи. Модель и представление полностью разделены, но код не элегантен, поскольку V и P ссылаются друг на друга. ViewModel достигает привязки представления и данных через привязку данных, которая устраняет недостатки этого MVP, но есть также проблема, заключающаяся в том, что привязка данных все еще незрелая.

Переход от Presenter к ViewModel с помощью привязки данных обеспечивает двустороннюю привязку данных, уменьшая связь между модулем просмотра и модулем управления. Я считаю, что с постоянным обновлением и улучшением технологии привязки данных Google режим MVVM будет более широко использоваться на платформе Android.

Ссылка:

Functional

От внешнего переходим к внутреннему — функциональному тестированию. Если в тестировании GUI мы проверяли наличие и внешний вид элементов, то в функциональном тестировании мы проверяем их работоспособность и взаимодействие.

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

Например:

Кнопка Зачем? После нажатия происходит какое-то действие.
Поле ввода Для передачи какой-то информации и взаимодействия с приложением.
Поиск Для того, чтобы пользователь мог быстро найти релевантную информацию.
Логин-форма Чтобы пользователи могли иметь доступ к определенным функциям приложения (или наоборот, ограничить их доступ).
Календарь Например, для выбора дат (билеты, бронирование и т. п.).
Дата и время Например, расписание прибытия транспорта.
Сообщения об ошибках Чтобы сообщить пользователю о том, что приложение работает некорректно, либо он делает некорректные действия.
Всплывающие окна и подсказки Направить пользователя по нужному сценарию.

У вас уже почти готов список тестовых сценариев. Зная целевое назначение любого элемента, мы можем легко описать все позитивные и негативные сценарии, необходимые для тестирования этого элемента.

Но и тут мы можем кое-что забыть. Часто забываемые проверки функциональных элементов приложения:

Кнопки:

  • Enter должна срабатывать как submit;
  • Tab должен переводить курсор на следующий элемент.

Поля ввода:

  • trimming («убирание») пробелов в полях ввода;
  • пустота/пробелы в поле ввода;
  • все способы редактирования (Insert, Delete, Backspace, Ctrl+C/V/X/Z и т. д.);
  • дроби ( 1.5 | 1,5 | ⅕).

Поиск:

  • wildcard symbols (* | ?);
  • написание поискового запроса слитно | раздельно | через дефис должно вести к одному результату;
  • ввод текста в другой раскладке.

Сообщения об ошибках:

пробуем отключить в настройках браузера.

Календарь:

  • 31 июня;
  • 29 февраля + не высокосный год;
  • прошлое/будущее (например, купить билет на уже прошедшее число).

Время:

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

логин (63 символа) @ домен (253 символа (может быть ip)).

Всплывающие окна / подсказки:

  • пробуем закрыть разными способами (нажатие на кнопку (если есть), на «крестик», клавишей ESC, просто нажатием в другую область экрана);
  • рефреш страницы особенно в момент запроса на сервер (например, совершение транзакции по покупке) иногда может приводить к появлению ошибок.

Функция main приложения

Как упоминалось ранее, каждый юнит-тест должен быть независимым исполняемым файлом. Это означает, что после создания юнит-теста вам понадобится функция для его запуска.

Для формирования кода функции , в соответствии с вашими потребностями, Qt Test предоставляет 3 макроса:

Вы можете добавить один из этих макросов в конец файла cpp, определяющего юнит-тест. В этом примере, поскольку я тестировал простой код на C++ (без Qt), я использовал:

Следует помнить, что если вы объявляете класс юнит-теста непосредственно в файле .cpp (а не в файле .h), вам нужно будет добавить в конце дополнительный :

Это требует Qt для правильной работы.

Пример создания карты тест-кейсов для UI-тестирования

Вокруг формы минимум 13 тест-кейсов. Сделаем разметку от TC-1 до TC-13 и выполним тестирование пользовательского интерфейса:

Пример покрытия тестами формы авторизации.

ТC-1

Проверить логотип, его положение и шрифт страницы.

ТC-2

  • Проверить правильность заголовка страницы.
  • Проверить шрифт

ТC-3

  • Проверить фокус курсора на поле по умолчанию.
  • Проверить обязательные поля, нажав кнопку «Далее», пока форма пуста.
  • Проверить положение и выравнивание текстового поля.
  • Проверить ввод как допустимых, так и недопустимых символов в метках полей.

ТC-4

  • Проверить положение и выравнивание текстового поля.
  • Проверить метки полей, убедитесь, что принимаются как допустимые, так и недопустимые символы.

ТC-5

  • Проверить положение и выравнивание текстового поля.
  • Проверить метки полей, убедитесь, что принимаются как допустимые, так и недопустимые символы.

ТC-6

  • Проверить сообщение об ошибке, введя разрешенные и запрещенные символы.
  • Проверить правильность сообщения об ошибке.

ТC-7

Проверить всплывающие окна и гиперссылки.

ТC-8

  • Проверьте метки полей, убедитесь, что принимаются как допустимые, так и недопустимые символы.
  • Проверьте положение и выравнивание текстового поля.

ТC-9

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

ТC-10

  • Проверьте положение значка.
  • Проверьте значок, показывает или скрывает пароль пользователя.
  • Проверить качество изображения.

ТC-11

  • Проверьте сообщение об ошибке, введя разрешенные и запрещенные символы.
  • Проверьте правильность сообщения об ошибке.

ТC-12

Протестируйте всплывающие окна и гиперссылки.

ТC-13

  • Протестируйте отправку данных.
  • Проверьте положение и ясность кнопки.

Usability

За внешним видом и функциональностью следует удобство (Usability). Не менее важная часть, так как от нее зависит, будет ли востребован ваш продукт вообще. О каких моментах нужно помнить при тестировании usability веб-приложения?

  • Соответствует ли приложение ожиданиям конечного пользователя;
  • Логичность интерфейса;
  • Самое нужное «сверху»;
  • Продуманная навигация;
  • Локализация (да, да, она относится и сюда тоже);
  • Совместимость с другим софтом (соцсети) и железом;
  • Скорость работы приложения;
  • Информативность (сообщения / обязательные поля);
  • Возможность отмены действий пользователя;
  • Help — должна быть инструкция, как работать с приложением;
  • Возможность печати (если нужно).

Почитать

Как обмануть Face ID

Biometric Authentication Under Threat: Liveness Detection Hacking — презентация с Black Hat, посвященная способам обмана биометрических сенсоров в смартфонах (датчик отпечатка пальца, сканер лица и сетчатки). Авторы приводят несколько способов обхода датчиков, в том числе с помощью прямого подключения к шине камеры и подачи на нее заранее снятого изображения (это позволяет обойти алгоритмы определения реального присутствия человека, но не лазерные сканеры в iPhone и некоторых других смартфонах). Но интереснее всего способ обмана сканера Face ID в iPhone X и более поздних моделях.

Во время сканирования iPhone строит подробную 3D-модель лица человека и требует, чтобы глаза были открыты. Такой подход сводит на нет почти все методы манипуляции, включая показ фотографии, видеозаписи, поднесение смартфона к лицу спящего человека и так далее.

Но у этого механизма есть фундаментальный изъян. При сканировании лица человека в очках он не может полагаться на 3D-сканирование глаз и переключается на куда более простой алгоритм: если в районе глаз есть белая точка на черном фоне — глаза считаются открытыми. Достаточно взять любые очки, наклеить на них два кусочка черной изоленты, нарисовать в их центре белые кружки, и вуаля: надеваем очки на спящего человека, подносим к его лицу смартфон — и экран разблокирован.

Очки для обмана Face ID

Реверс-инжиниринг прошивок IoT-устройств

How to Start IoT device Firmware Reverse Engineering? — введение в реверс-инжиниринг прошивок различных IoT-устройств, таких как роутеры, камеры, устройства для умного дома и так далее. Статья короткая, простая, но содержит несколько вводных рекомендаций, которые могут пригодиться новичкам.

  1. Любой реверс начинается с поиска самой прошивки. Обычно ее можно скачать с сайта производителя или на форумах.
  2. Зачастую прошивки распространяются в zip-архиве, внутри которого находится файл с расширением .bin.
  3. Обычно файл .bin — это сплав из загрузчика, ядра Linux и образов одного или нескольких разделов. Чтобы узнать адреса смещений, по которым находятся эти образы в файле, можно использовать утилиту :
  1. Адрес смещения можно использовать, чтобы извлечь образ раздела с помощью утилиты (в данном случае образ корневой файловой системы squashfs):
  1. Получить содержимое файловой системы squashfs позволяет утилита :
  1. На этом все, можно начинать анализ содержимого прошивки.

Типы MVP

Существует несколько основных подходов к созданию MVP. В зависимости от этого выделяют несколько типов такого продукта.

Волшебник страны Оз

Волшебник страны Оз использовал трюки, чтобы притворяться тем, кем он на самом деле не был. То же можно сказать о данном типе MVP. Продукт только кажется функциональным, но на самом деле его разработчик делает всю работу вручную. Это нужно для того, чтобы проверить саму концепцию продукта и понять, востребован ли он. Так развивался сайт заказа обуви Zappos. Изначально у авторов идеи не было ни склада, ни закупленных партий товара, а существовал лишь сайт с фотографиями обуви. Когда ее начали заказывать, разработчики обновили функциональность сайта.

MVP-консьерж

Продукт работает по тому же принципу, что и в случае с Волшебником страны Оз: изначально все работы выполняются вручную. Однако клиенты при этом осознают, что за товаром или услугой стоит человек. Сотрудники службы финансового планирования и инвестиций Wealthfront изначально общались напрямую с клиентами, которым нужна была помощь в управлении капиталом, а автоматизированная система появилась позднее. Такой тип MVP помогает сформировать план развития продукта и собрать фидбэк от целевой аудитории.

Разрозненный MVP

Продукт с одним параметром

Это рабочий продукт с минимальным набором функций, которые нужно проверить. Такой тип MVP позволяет сформировать целевую группу, получить обратную связь и проанализировать ее, а также провести тестирование функциональности.

Место автоматизации GUI в процессе разработки

Для успешного тестирования с применением автоматизации необходимо определиться с местом автотестов в процессе разработки. Поскольку при помощи автоматизации GUI покрываются в основном регрессионные сценарии, то есть смысл запускать тесты для каждой новой сборки. Для этого мы используем Jenkins. После каждого успешного билда автоматически стартует сборка проекта с тестами. Также есть возможность ручного запуска или по расписанию, для запуска тестов ночью — в момент минимальной нагрузки на тестовые стенды.

Инструменты для автоматизации GUI

Путем проб и ошибок мы в Ukad пришли к следующему инструментарию для GUI автоматизации:

  • Java — как язык для написания тест-скриптов.
  • Maven — для сборки проекта.
  • Selenide — как фреймворк для написания GUI тестов.
  • TestNG — как фреймворк для управления запуском тестов.
  • Selenoid — для непосредственного управления сессиями браузера.
  • Allure — для создания и эффектной презентации отчета.
  • Jenkins — для непрерывной интеграции тестов в процесс разработки.

Более подробно об инструментах и причинах, почему мы выбрали именно этот набор:

  • Java. Мы используем Java, так как это путь наименьшего сопротивления ведь сообщество просто огромно, что дает доступ к большому количеству готовых решений для тестирования и не только. Это в свою очередь позволяет не тратить много времени на исследование и решение часто возникающих проблем, так как очень велика вероятность того, что решение уже найдено.
  • Maven. Можно использовать любой другой сборщик. Для автотестов это не принципиально, но лично мне Maven ближе.
  • Selenide позволяет не изобретать свой велосипед для решения стандартных проблем Selenium (таких как ожидания и поиск элементов на странице, добавление «мягких» проверок и т. д.) и значительно повысить скорость разработки и стабильность тестов.
  • TestNG. Мы перешли с Junit на TestNG для использования наборов на основе .xml файлов, а также возможности объединения тестов в группы.
  • Selenoid. Мы используем Selenoid вместо Selenium Hub, так как он более стабилен и позволяет запускать сессии браузеров в Docker контейнерах, плюс добавляет такие приятные бонусы, как просмотр выполнения конкретного теста и запись видео его прохождения.
  • Allure. Позволяет значительно расширить возможности стандартного TestNG отчета, эффектно и удобно презентовать всю информацию о пройденных сценариях. В репорте каждый член команды сможет найти для себя полезную информацию. Начиная от времени и количества пройденных сценариев с результатами прохождения, до прикрепленного видео прохождения и скриншотами для упавших тестов.
  • Jenkins. Мы используем Jenkins для сборки некоторых своих проектов, поэтому мы решили использовать его же для сборки тестов. Также с Jenkins удобно интегрировать Allure репорты при помощи дополнительного плагина.

Настройка проекта

Идея Qt Test заключается в том, что каждый тестовый случай должен быть независимым исполняемым файлом и иметь собственный проект.

Самый быстрый способ создать проект – использовать шаблон «Проект автотестирования» (Auto Test Project), который находится в группе «Другой проект» (Other Project) диалогового окна «Новый проект» (New Project).

Рисунок 1 – Создание проекта автоматического тестирования в Qt Creator для модульного тестирования кода на C++ с помощью Qt Test

Мастер проведет вас через настройку проекта. В частности, в разделе «Подробнее» (Details) можно указать несколько параметров.

Рисунок 2 – Детали настройки проекта автотестирования в Qt Creator

«Имя теста» (Test case name) будет именем класса, представляющего юнит-тест.

Если вы не хотите использовать мастер проекта, вам нужно добавить в переменную в qmake файле проекта:

Если в вашем модульном тесте нет элементов графического интерфейса, можно отключить модуль :

GUI

GUI — у любого тестируемого предмета и веб-приложения есть внешний вид, поэтому тестирование графического интерфейса или попросту, внешнего вида — это самое первое, что мы можем сделать. Сравнить его с требованиями и/или с макетом и все. Или не все? А как насчет верстки?

Верстка — размещение элементов веб-приложения (изображения, текст, кнопки, видео…) в соответствии с макетом или требованиями.

Проверяем:

  • наличие всех элементов;
  • их размер и цвет;
  • расположение относительно друг-друга.

Все? — Нет :) У верстки есть еще множество параметров и элементов, которые мы очень часто забываем проверить.

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

Измерение размеров элемента — если это имеет значение, то померять размеры элемента и сравнить их со спецификацией можно с помощью, например Page Ruler.

Правильность шрифтов (название, размер, цвет) — WhatFont.

Цвета интерфейса — ColorZilla.Контент — проверить на наличие орфографических и грамматических ошибок (SpellChecker).

Появление курсора — довольно часто мы забываем проверить, появляется ли вообще и как выглядит курсор в полях ввода, на кликабельных элементах.

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

Обозначение возможности переноса элементов.

Кодировка (UTF8…).

Стандарты HTML/CSS — достаточно неплохие решения для быстрой проверки предлагает W3C.

Заголовки по всему приложению должны быть приведены к одному стандарту (пример).

Title страницы — о нем мы тоже часто забываем, также как и разработчики :)

Back button — достаточно часто встречается ошибка при переходе на какую-то страницу и нажатии на браузерную кнопку Back, предыдущая страница крашится или возврат на нее вовсе не осуществляется.

Масштабируемость — особенно это важно при тестировании на смартфонах и планшетах. Где пользователь часто меняет масштаб экрана (Window Resizer), а также режим адаптивного дизайна (например в FireFox Developer Edition)

Кроссбраузерность — одна и та же страница может выглядеть по-разному в разных браузерах (пример).

Проверяем Scroll.

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

Проверить контент при отключенных (режим WebDeveloper) изображениях, flash, JavaScript.

Все? — Нет :)

Локализация — что мы знаем об этом? Обычно наши знания сводятся к невнятным «ну, это язык», «кодировка», «раскладка», еще реже «геолокация». Что еще мы так часто забываем проверять в рамках тестирования локализации?

Проверяем тестовый образец на правильность перевода — тут, конечно, хорошо бы подключить переводчика или носителя языка, но за неимением таких, берем тестовый образец и переводим через любой онлайн-переводчик (ну и все мы помним, как прекрасно и весело читать описание товаров на русском языке на AliExpress).
Длина переведенных слов — количество символов в переведенном слове может быть гораздо больше (пример), что может привести к «расползанию» интерфейса при переводе.
Сокращения/аббревиатуры — существуют правила, по которым их либо переводят, либо транслитерируют, либо оставляют как есть.
Валюта.
Параметры шрифта могут также значительно отличаться в зависимости от языка ввода.
Проверить работу поиска во всех локализациях — к примеру, на AliExpress результаты поиска одного и того же слова «смартфон» дают разный результат по количеству найденных товаров, причем разница исчисляется десятками тысяч.
Мета-информация (keywords/title/description) — столь незначительное для пользователя, невидимое, но такое важное для поисковых машин и продвижения сайта в гугле и других поисковиках.
RTL (right to left languages) — языки c обратным написанием (арабский, иврит) имеют свои особенности: числа пишутся слева направо, значки и иконки отзеркаливаются, названия программ не переводятся, нет переносов, кнопки редактирования Backspace и Delete работают наоборот.

Библиотеки

  • AndroidX Tech — сайт с дополнительной информацией о библиотеках семейства Android X;
  • Colibri — библиотека для автоматизированного тестирования UI приложения;
  • Ulfberht — написанный на Kotlin DI-фреймворк;
  • Submarine — всплывающая панель навигации;
  • Coil — написанная на Kotlin библиотека для загрузки изображений, быстрая и легкая альтернатива Picasso и Glide;
  • sign-in-with-apple-button-android — Android-библиотека для аутентификации с помощью сервиса Sign In with Apple;
  • finch — панель для инспекции okHttp-трафика;
  • kotlin-multiplatform-template — готовый темплейт для мультиплатформенного Kotlin-приложения, в комплекте: бэкенд, фронтенд, Android-приложение и iOS-приложение;
  • Bulldog — библиотека, упрощающая работу с SharedPreferences;
  • SimpleGenericAdapter — универсальный адаптер для RecyclerView;
  • ProgressView — анимированный гибко настраиваемый виджет прогресса;
  • BottomNavigator — библиотека для навигации между фрагментами с помощью табов в нижней части экрана.

Читать новость в источнике Xakep

4.2 UI интерфейс интерфейса

Чтобы хорошо понять MVP, у вас должна быть возможность взаимодействовать с пользовательским интерфейсом. Посмотрите на интерфейс ниже и выделите пользовательский элемент управления, отмеченный красным, чтобы получить интерфейс ниже.

public interface IUserAdd 
{ 
       event EventHandler UserAddEvent;
       string UserName { get; set; }
       string UserAge { get; set; }
}

Два поля ввода в интерфейсе разделены на два атрибута: UserName и UserAge. Событие нажатия кнопки «Сохранить» абстрагируется в событии UserAddEvent. Код для реализации этого интерфейса в winform выглядит следующим образом:

public partial class UserAdd : UserControl, IUserAdd 
{ 
       public event EventHandler UserAddEvent; 
       public string UserName 
       { 
           set { this.txbName.Text = value; } 
           get { return this.txbName.Text; } 
       }

       public string UserAge 
       { 
           set { this.txbAge.Text = value; } 
           get { return this.txbAge.Text; } 
       }

       public UserAdd() 
       { 
           InitializeComponent(); 
       }

       private void btnAdd_Click(object sender, EventArgs e) 
       { 
          if (UserAddEvent != null) UserAddEvent(this, e); 
       } 
   }

Возьмем атрибут UserAge, чтобы объяснить волшебство интерфейса UI. Когда внутренний код хочет получить значение возраста в интерфейсе, ему нужен только атрибут get, а когда он хочет обновить отображение интерфейса, ему нужен только атрибут set. В это время работа внутреннего кода интерфейса абстрагируется в операции атрибута UserAge, который не имеет отношения к конкретному отображению интерфейса.

Заключение

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

Например, упомянутый здесь уже неоднократно Фаулер, выделяет аж три возможных модификации 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 «шкурку».

Рейтинг
( Пока оценок нет )
Понравилась статья? Поделиться с друзьями:
Все про сервера
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: