Прочитал “классическую” книжку GoF’ов
Наверняка вам, как и мне, все уши прожужжали шаблонами проектирования. Вот и решил я привести свои мозги в соответствие с веяниями моды и прочитать классическую книжку “банды четырех”.
Книжка хоть и интересная, но читается довольно туго – иногда перевод сильно хромает. В начале книжки есть пример архитектуры WYSIWYG-редактора, на которой показывается реальное применение шаблонов проектирования. Я читал этот раздел только после того, как прочитал справочник шаблонов.
Я пытался не просто читать книжку, но и писать текущие программы с использованием шаблонов. Были как положительные, так и отрицательные стороны. Я убедился, что шаблоны – не панацея.
Самым адским опытом стало применение шаблона State для простенькой машины состояний. Код раздулся так, что я там чуть не потерялся. Получилось очень некрасиво. С другой стороны, та-же машина состояний, вынесенная в отдельный поток уместилась в одну страницу.
В любом случае, шаблоны учат правильно разбивать системы на объекты. Что касается применения шаблонов во встраиваемых системах, то оно весьма ограничено тем, что у нас часто нет освобождаемой динамической памяти.
Итак, пройдемся по шаблонам и я опишу, какое применение их я вижу в эмбедде:
Порождающие паттерны
- Abstract Factory – тут вроде все понятно, в зависимости от состояния ножки при загрузке система может выполнять несколько разных функций, определяемых некими классами. Эти классы создаются только при запуске.
- Builder – применение не ограничено, билдер может быть и статическим. Можно строить пакеты, собирать систему из заранее созданных кусочков, итп.
- Factory Method – к сожалению, не особо полезен – нужна динамическая память.
- Prototype – можно приводить один статический объект в соответствие другому. Хотя, для этого можно просто использовать memcpy
- Singleton – применение неограниченно, хотя народ считает синглтоны дурным тоном. К примеру, модуль управления блоком питания может быть синглтоном.
Структурные паттерны
- Adapter – тут вроде как все понятно – адаптируем что-то одно к интерфейсу чего-то другого. Необходимости в нем у меня пока не возникало.
- Bridge – может использоваться в драйверах. К примеру, абстракциями могут быть Uart и UartWithHandshaking, а реализациями – LpcUartImpl, Stm32UartImpl. Хотя, если у вас прямо аж такие требования к переносимости, нужно задуматься.
- Composite – не очень применимый шаблон из-за ограниченности памяти. Для него придется использовать пулы объектов. Я использовал его для конструирования меню.
- Decorator – вполне себе применимый шаблон. Я использовал его, чтобы передавать данные, предназначенные для RS232 по RS485 сети.
- Facade – пока у меня небыло таких “огромных подсистем”, для которых необходим был бы фасад.
- Flyweight – лично я часто его использую, хотя мне это и не нравится. По-моему, Flyweight очень сильно нарушают инкапсуляцию, сохраняя свое состояние во внешнем объекте.
Я использую Flyweight как-раз тогда, когда нужно обойти отсутствие динамической памяти.
Пример из практики – класс, считывающий информацию с устройства, которому передаются данные о том, откуда и куда ее считывать.
- Proxy – Пример: по приему каждого байта в пакет нужно обнулить таймаут.
Паттерны поведения
- Chain of Responsibility – у меня используется для приёма нескольких разных пакетов. Если байт не подошел одному пакету, то передается другому.
- Command – используется для обработки команд, присланных с компьютера.
- Interpreter – требует динамической памяти, даже и не знаю, где его применить. По-моему он чересчур жирный даже для ПК.
- Iterator – применяется для перечисления приборов, находящихся на связи, Списка переменных, полученный от приборов да и много еще где. Очень полезный паттерн.
- Mediator – у меня применяется для передачи данных между устройствами. Сами интерфейсы устройств не знают друг про друге.
- Memento – если показываем пользователю меню, где он может выбрать Ok или Cancel, то состояние до редактирования можно запомнить в Memento.
- Observer – я использую обзервер для слежки за ножками с прерываниями. Несколько частей программы могут подписаться на события типа “возрастающий фронт” или “спадающий фронт” такой-то ножки. Может показаться, что это жирно, но у меня во многих местах не требуется прямо такая уж мгновенная реакция, микросекунда задержки вполне допустима.
- State – я уже рассказал о своём негативном опыте. Хотя, паттерн и красивый, но я его нигде не использую. Принципиальных ограничений нет, все состояния можно создать статически, но код получается слишком уж жирным.
- Strategy – очень полезный шаблон. С помощью него я делаю абстракцию от аппаратуры, да и многое другое.
- Template Method – мой прибор может считывать данные с нескольких типов устройств. Алгоритм считывания задается шаблонным методом, а сам доступ к данным – подклассами типов устройств.
- Visitor – его я нигде не использую, просто не было необходимости. Принципиальных ограничений нет.
Стоит ли читать эту книгу эмбеддеру? Думаю, да, особенно, если вы считаете, что ООП есть место в эмбедде и если вы не совсем новичок.
Если есть минутка, опишите, как вы применяли шаблоны проектирования в эмбедде!
Читал эту книжицу некоторе примеры довольно искуственны. Имхо паттерны не должны быть самоцелью, а должны появляться в процессе рефакторинга.
P.S.
Не думал, что паттерны можно в эмбединге применить)))
Насчет примеров — согласен. А эмбеддинг нынче мало чем отличается от обычного программирования.
» шаблоны – не панацея»
Серебряной пули не существует… ( https://en.wikipedia.org/wiki/No_Silver_Bullet )
Шаблоны и динамическая память — совершенно параллельные вещи.
Шаблоны — это своеобразное средство расширения возможностей препроцессора и автоматизации проектирования. В эмбеде совершенно спокойно применяется, даже на 8-битниках с килом ОЗУ. Чтобы проникнуться, почитайте Александреску.
Для многих шаблонов просто необходима динамическая память (к примеру, Factory Method тело которого фактически состоит из создания экземпляра объекта).
тоже читал эту книгу оказалась слишком нудной
советую эмбеддеру читать вначале
Гради Буч: Объектно-ориентированный анализ и проектирование
https://www.proklondike.com/books/oop/buch_ooad.html
Более интересно написана
темболее с новыми тенденциями ШП встраивается в семантику языка (C#)
У меня сейчас Фаулер, потом книжка по UML, и только потом будет Буч.
Скажите, а как при помощи Стратегии Вы умудряетесь сделать абстракцию от аппаратуры???? (я только начинаю примерять паттерны, новичок)
Спасибо!
Вот еще собственно неплохая и достаточно простая книга:
А. Шевчук «Design Patterns via C#» (https://itvdn.com/ru/patterns)