Façade and AOP

Давненько я не писал по теме шаблонов и аспектов. И этот пост будет для разогрева темы снова.

До этого были рассмотрены шаблоны, которые в той или иной степени получают профит от использования Аспектно-Ориентированного программирования. Однако есть один, который не получит никакой пользы от АОП. Сама суть шаблона «Фасад» заключается в том, чтобы выделить отдельный интерфейс для облегчения доступа к некоторой сложной подсистеме.

facade_aop

Википедия дает следующее определение:

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

С помощью аспектов не выделить отдельный класс для такого функционала.

По сути, исследователи признали, что только «Фасад» никоим образом из классических 23 шаблонов не может быть хотя бы частично реализован с помощью АОП.

Вот такой короткий рассказ.

 

Hard’n’Heavy!

Бэкенд и «золотые молотки»

Привет, коллеги!

Мы анонсировали конференцию, посвященную Desktop UI & Business Application. В поддержку, чтобы посмотреть на настроения публики, была опубликована статья «WPF живее всех живых», которая оказалась дискуссионной и заставила нас в несколько другом свете взглянуть, на то, что и как мы хотим донести до широкой публики.

Как показали комментарии, не WPF единым живет десктоп разработка. Есть порты Qt для .NET, есть WinRT, если в эпсилон окрестности от дефолт-сити есть спецы по этим технологиям, которые хотят высказаться – у нас есть трибуна! Для этого все и задумано, чтобы показать различные варианты для ваших проектов.

Буквально вчера закончилась онлайн конференция dotNetConf 2015, которую, исходя из сообщений, Microsoft скорее возродила, нежели придумала заново. Конференция, судя по содержанию старается покрыть все основные области использования языка, это мультиплатформенность, веб, десктоп, доставка приложений, интеграция с Xamarin, будущее .NET, .NET Core, Roslyn Analyzer и другие темы. На мой взгляд, это генеральная репетиция перед конференцией //build, которая состоится в конце апреля-начале мая.

Подробнее

Шаблон Хранитель в АОП реализации

Вторым на очереди в описании оказался шаблон проектирования Хранитель (Memento). На мой взгляд этот шаблон достаточно просто реализовать, по крайней мере его идеологическая суть ясна многим без детальных объяснений.

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

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

Общая информация

Для полноты картины, я считаю, что надо все так же привести основные характеристики и назначение шаблона.

Хранитель относится к категории Поведенческих шаблонов.

Намерение

В вашей системе необходимы точки отката данных. Например, вы разрабатываете приложение, которое позволяет пользователям активно редактировать данные. Хорошим тоном является дать возможность пользователю откатывать назад сделанные изменения и не один раз, а последовательно, один за одним, до предыдущего явно сохраненного состояния данных. Фактически это всем знакомый функционал undo/redo.

Суть

Сохранить состояние объекта, и иметь возможность вернуться к исходному состоянию, не раскрывая своего содержимого внешнему миру.

Очень важным моментом является — «не раскрывая своего содержимого внешнему миру» — это суть инкапсуляции и ООП. В качестве быстрого примера, могу привести пример с объектом, который получает при конструировании уникальный номер. Этот номер нельзя никак задать с помощью публичного API. При восстановлении объекта из Memento есть доступ к внутренним полям и эта операция пройдет абсолютно честно и просто.

Реализация

Классическая реализация говорит о следующих особенностях реализации шаблона:

  • Необходимо создать класс-хранитель «мгновенных снимков» целевого класса
  • Целевой класс должен уметь сохранять и принимать свои «мгновенные снимки»

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

memento

Подробнее

Шаблон Одиночка в реализации AOP

Любое больше дело лучше начинать с чего-то простого, чтобы простой войти во вкус. Я считаю, что рассмотрение реализации всех шаблонов с помощью Аспектно-Ориентированного Подхода (АОП) лучше всего начать с шаблона Singleton – как самого простого в понимании. В этой статье я не буду затрагивать вопросы в чем хорош шаблон, в чем плох, почему некоторые считают, что это уже анти-шаблон, который уже совсем не стоит использовать в чистом виде как есть. Всю эту информацию можно сравнительно легко найти на просторах интернета. Я же хочу посмотреть, как будет отличаться реализация шаблона в АОП стиле от, скажем так, классической.

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

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

  • Проверка правильности шаблона с точки зрения дизайна. За это отвечает архитектурный фреймворк в составе PostSharp.
  • Легкая работа с многопоточными моделями. Это важно в контексте создания объекта Одиночки.
  • Легкая навигация и подсветка используемых аспектов в самой Visual Studio.

 

Общая информация

Для полноты картины, я считаю, что надо снова привести основные характеристики и назначение шаблона.

Намерение

Лучше, когда некоторые объекты представлены только в одном экземпляре, для того, чтобы избежать путаницы и хаоса. Например, единая бухгалтерская книга, правительство, спулер принтеров. Когда таких объектов больше одного, то могут и часто возникают неприятные ситуации, которые ведут к нарушению целостности данных, трудностям с понимании логики работы в run-time.

Суть

В системе может существовать только один экземпляр класса, доступ к которому осуществляется через глобальную точку доступа

Реализация

Каноническая реализация говорит о следующих особенностях реализации шаблона:

  • Все конструкторы должны быть приватными.
  • Доступ к объекту осуществляется через статическое поле.
  • Объект создается в момент первого обращения и в дальнейшем отдается один и тот же объект.

Вот в целом и все нехитрые особенности реализации. В UML нотации шаблон выглядит следующим образом:

singleton

Подробнее

АОП и шаблоны проектирования GoF

Давно меня занимает тема аспектно-ориентированного программирования в виду моей исключительной профессиональной лени. Мне не нравится писать тупой и повторяющийся код. Однако это словно родовое проклятье, когда дело касается разных инфраструктурных вещей при написании кода. Начиная с банального и уже набившего оскомину при упоминании АОП – логировния и заканчивая кэшировнием и реализацией особенного процесса по перехвату исключений. Аспекты могут быть применены к гораздо большему спектру задач. К неочевидному на первый взгляд спектру задач, о котором большинство даже не задумывается. Например, шаблоны проектирования «банды четырех».

Конкретная реализация с помощью аспектов сильно зависит от АОП фреймворка. Например, к какому типу он относится: прокси или внедрения в код. Я свой выбор остановил на PostSharp, с которым знаком с версии 1.2 или 1.3, мне кажется было что-то около этого. И то, что было тогда и есть сейчас — значительно отличается по функционалу и простоте использования. Не в малой степени благодаря эволюции самого языка C#.

Шаблоны проектирования появились не просто так. Это повторяющиеся задачи, реализовывать которые приходится на каждом проекте, часто в сильной связке с доменом, перелетая код домена с инфраструктурой шаблона. При таком подходе шаблоны приходится каждый раз писать заново. Правильная реализация ООП подхода дает возможность сделать приложение менее связанным, но код значительно усложняется. С учетом обеспечения безопасности самих данных и доступа к ним, код может значительно разрастаться, так как эти требования плохо адресуются ООП подходом.

Подробнее

SoftLab.NET 2014

20 Декабря была веб-конференция SoftLab.NET 2014 компании Luxoft на которой я рассказывал про Threading Pattern Library из комплекта поставки PostSharp. Эта библиотека шаблонов действительно упрощает работу с многопоточностью. В следующем году я хочу подробно про это написать, так как там много нюансов обнаруживается, но сейчас краткий обзор доступен в презентации.

Hard’n’Heavy!

Логика на INotifyProperyChanged

Сложность 200-300

В основном я пишу о практических подходах, конкретных реализациях идей и достаточно редко об общей структуре приложений. Как они строятся, как лучше разрабатывать приложения, какие подходы лучше поддерживаются и так далее. Я думаю, что все согласятся, что нельзя написать единое руководство по тому как надо писать приложение. Если бы такое можно было написать, то такое руководство давно было бы написано людьми гораздо более умными и выдающимися, чем я на текущий момент =) Наверно, если бы такое руководство существовало, то наша профессия была бы не столь востребована и весь рынок разработки захватили китайцы и индусы, так как они более усидчивы и исполнительны. К счастью такого руководства пока что нет, да и вряд ли появится, так что смекалка и нестандартность подходов все еще играет на нашей стороне.

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

Я уже не раз писал и говорил насколько мне не нравится явная реализация INPC при реализации MVVM для WPF, но недавнее открытие в проекте коллег не смогло меня оставить равнодушным. Честно сказать, я не представлял, что таким образом можно построить логику приложения, но что есть, то есть. Итак, не будем более затягивать вступление и обратим взор на код.

Подробнее

Конвейер (Pipeline) — IV

Ближе к жизни

Предыдущий пример стоит достаточно далеко от жизни, так как часто не требуется выполнять последовательно задачи из одного сервиса. Чаще всего бывает несколько сервисов, которые работают над своими задачами. Требуется их как-то красиво связать в одном месте, чтобы это было понятно и прозрачно. Собственно такой пример я и собираюсь показать. Запомните сколько строчек кода понадобилось для описания предыдущего примера и сколько это займет в конце.

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

Вообще ничего сложного. Каждый класс делает свою работу заданное количество времени и по истечению времени публикует значение дальше.

Подробнее

Конвейер (Pipeline) — III

Конвейер для больших массивов

Редко кода требуется создать конвейер для небольшого количества данных. Даже не так. Конвейер по сути своей предназначен для неопределенного количества данных, когда неизвестно наперед сколько их будет, но что будет много – известно.

До этого я специально взял количество данных в наборе равное четырем. Так как это еще разумное количество потоков для многопроцессорных машин. Для экспериментов приближенным к реальности можно взять количество элементов равным 60.

По сути код останется тем же, только надо увеличить количество элементов.

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

При работе с Task, замеры времени показывают среднее значение обработки в 51 секунду. Это означает, что все 60 потоков не создаются одновременно, а выстаиваются в какую-то очередь и все это безобразие занимает 51 секунду (разброс от 50 до 53 секунд), если использовать такой код:

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

Подробнее

Конвейер (Pipeline) — II

Конвейер для небольших массивов

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

Обработка одного значения совсем не интересно, гораздо интереснее посмотреть временные затраты при небольших массивах. Для начала пусть будет 4 значения в массиве.

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

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

Подробнее