Обратные вызовы в C++ - [12]
2.5.5. Преимущества и недостатки
Преимущества и недостатки реализации обратных вызовов с помощью лямбда-выражения приведены в Табл. 6.
Табл. 6. Преимущества и недостатки обратных вызовов с помощью лямбда-выражения
Гибкое управление контекстом. Возможность захвата переменных предоставляет простые и удобные средства изменения контекста. Изменяя состав захваченных переменных, мы легко можем добавлять значения, необходимые для контекста, при этом нет необходимости изменять код инициатора. Захватив указатель this, мы получаем доступ к содержимому класса, т. е. фактически лямбда-выражение превращается в «метод внутри метода» (см. пример в Листинг 22). Элегантно, не правда ли?
Требует использования шаблонов. Использование шаблонов накладывает архитектурные ограничения на реализацию программных модулей. Это связанно с тем, что шаблоны не предполагают присутствие предварительно откомпилированного кода. Подробнее об этом мы будем говорить в соответствующей главе (4.7), посвященной ограничениям при использовании шаблонов.
>class EventCounter
>{
>public:
> void AddEvent(unsigned int event)
> {
> callCounter_++;
> lastEvent_ = event;
> }
>private:
> unsigned int callCounter_ = 0;
> int lastEvent_ = 0;
>};
>class Executor
>{
>public:
> Executor(EventCounter* counter): counter_(counter)
> {
> auto lambda = [this](int eventID)
> {
> //It will be called by initiator
> counter_->AddEvent(eventID);
> processEvent(eventID);
> };
> //Setup lambda in initiator
> }
>private:
> EventCounter* counter_;
> void processEvent(int eventID) {/*Do something*/}
>};
2.6. Итоги
В C++ обратные вызовы могут быть реализованы с помощью следующих конструкций:
• указатель на функцию;
• указатель на статический метод класса;
• указатель на метод-член класса;
• функциональный объект;
• лямбда-выражение.
Каждая реализация имеет свои достоинства и недостатки. Так какую все-таки выбрать? Чтобы ответить на этот вопрос, необходимо выполнить сравнительный анализ.
3. Сравнительный анализ реализаций
3.1. Методологические подходы
3.1.1. Обобщенный алгоритм
Итак, мы рассмотрели различные способы реализации обратных вызовов. Какая из них наилучшим образом подходит для использования в конкретной ситуации? Чтобы ответить на этот вопрос, необходимо сравнить реализации, т. е. требуется сравнительный анализ.
Обобщенный алгоритм сравнительного анализа включает следующие шаги.
1. Выбрать объекты анализа.
2. Определить критерии сравнения.
3. Построить матрицу соответствия, в которой отобразить, насколько объекты анализа соответствуют выбранным критериям.
4. Проанализировать полученные результаты и выбрать объект, наилучшим образом удовлетворяющий совокупности критериев.
Рассмотрим указанные шаги подробнее.
1. Объект анализа – это некая сущность, которая будет подвергаться анализу. В нашем случае такими сущностями выступают реализации обратных вызовов.
2. Выбор критериев – пожалуй, самый сложный и в то же время наиболее важный этап сравнительного анализа. Критерии должны отражать значимость показателя, который они определяют; неверный выбор критериев приводит к неправильным результатам. Так, например, в качестве критерия можно выбрать количество строк кода, но насколько этот показатель значим при разработке? В нашем случае совершенно не значим: не имеет значения, займет реализация 10 или 50 строк, важно то, насколько она обеспечивает качество выполняемых функций. Качество, в свою очередь, определяется степенью выполнения требований, предъявляемых к проектируемой системе. По этой причине именно требования наилучшим образом подходят для использования в качестве критериев.
3. Матрица соответствия строится в виде таблицы. В заголовки строк таблицы вписываются критерии, в заголовки столбцов – объекты анализа. В ячейках таблицы для каждой пары «объект-критерий» выставляется степень соответствия объекта заданному критерию. Степень выполнения может быть качественной (выполняется/не выполняется) или количественной (выставляется оценка по заданной шкале).
4. Полученные результаты суммируются. Объект, набравший наибольшее количество положительных утверждений (качественная оценка), или наибольшее количество баллов (количественная оценка), будет оптимальным.
Итак, мы описали обобщенный алгоритм сравнительного анализа. Далее рассмотрим, как выполняются шаги алгоритма применительно к поставленной задаче – выбору оптимальной реализации для конкретного случая. Первый шаг – выбор объектов анализа – здесь тривиальный, объектами анализа являются реализации обратных вызовов. Перейдем ко второму шагу –определим критерии, в качестве которых выступают требования.
3.1.2. Требования как критерии
Обозначим требования, предъявляемые при разработке программного кода обратных вызовов. Состав требований не претендует на полноту, читатель может добавить свои, если посчитает их значимыми или актуальными для конкретного случая.
Простота. Показывает, насколько просто и быстро можно написать, отладить и сопровождать код.
Независимость компонентов. Показывает, нужно ли изменять код одного компонента при изменении другого. Чем меньше зависимости между компонентами (в нашем случае это инициатор и исполнитель), тем проще разработка и отладка программной системы. Кроме того, упрощается ее сопровождение и повышается надежность.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.