четверг, 26 февраля 2015 г.

О сложности

Фред Брукс в своем «Мифическом человеко-месяце» еще 30 лет назад описал пару понятий, которые я считаю ключевыми в проектировании. Это понятия случайной (accidental) и естественной (essential) сложности.

Разница между ними в том, что естественная сложность является частью самой задачи и от нее невозможно избавиться. Случайная сложность привносится в процессе решения и обусловлена ошибками проектирования, плохим выбором языка программирования или базы данных, неудачной декомпозицией системы и просто грязным кодом. Все эти иерархии наследования, принципы проектирования, cohesion & coupling, все это направлено на уменьшение случайной сложности. На то, чтобы обуздать естественную сложность задачи и сделать ее максимально очевидной.

Мне кажется, очень важно осознавать разницу между этими понятиями.

Сколько раз вы ловили себя на мысли, что совершенно не можете понять, что же делает некоторый код? Вы видите кучу блоков if-else, switch, foreach, перехват и логирование исключений. Все это хорошо. Но, какую же задачу этот код решает на самом деле? Затем вы начинаете распутывать этот клубок, добавляете комментарии, выделяете новые методы, переносите обработку исключений на более высокий уровень, и оказывается, что решается очень простая задача, которую можно описать парой предложений.

вторник, 6 января 2015 г.

Ретроспектива 2014

Прошел Новый Год, на носу Рождество, а значит пришло время подводить итоги прошедшего года.

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

Специфичных постов о языке C# практически не осталось, хотя хорошо это или плохо, сказать сложноJ. В этом году я планирую добить книгу по паттернам, а значит, часть постов будет посвящено именно этой теме. С переходом в Майкрософт времени стало немного меньше, но желание писать пока не убавилось.

Ниже представлен перечень наиболее интересных и значимых постов, сгруппированных по тематике. Гляньте, а вдруг чего-то интересное пропустили!

SOLID принципы
Паттерны проектирования
Философия программирования
Другое
C#/.NET
Книги

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

понедельник, 29 декабря 2014 г.

О менторах и менторстве

В некотором роде этот «капитанский» пост можно считать продолжением популярного прошлогоднего поста Увлеченный программист, в котором тема менторства уже поднималась.

Многие из нас хотели бы в жизни встретить настоящего Учителя, который бы раскрыл все секреты бытия и научил бы читать регулярные выражения, написанные другим человеком. Десятку человек в мире повезло и они встретили своего мудрого наставника, когда он им был нужен и они были готовы воспринимать его мудрость. Остальным миллионам бедных программистов повезло не так сильно.

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

понедельник, 22 декабря 2014 г.

Фильтры исключений в C# 6.0

Одной из новых возможностей языка C# 6.0 являются фильтры исключений.

Общая идея довольно простая: рядом с блоком catch появляется возможность задать некоторый предикат, который будет определять, будет ли вызван блок catch или нет.

clip_image002

Данный вариант синтаксиса доступен в публичной версии VS2015, но он будет изменен в финальной версии языка C#. Вместо if будет использоваться ключевое слово when.

четверг, 11 декабря 2014 г.

Интерфейсы vs. Абстрактные классы

DISCLAIMER: ниже речь идет об интерфейсах и абстрактных классах на платформе .NET. Большая часть рассуждений применима и к другим языкам, с разделением понятий интерфейсов и классов.

Между интерфейсами и абстрактными классами нет особой разницы с точки зрения моделирования. И то, и другое определяет «абстрактный интерфейс» семейства объектов и разница есть лишь в том, существует ли поведение по умолчанию или нет.

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

Разница появляется с точки зрения языка программирования, разработчики которого решили не морочить голову с полноценным множественным наследованием: «ромбовидным наследованием», конфликтами имен из разных базовых классов и т.п. вещами.

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

понедельник, 8 декабря 2014 г.

Для чего нужны интерфейсы?

В чем сила интерфейсов? Сила интерфейсов в правде слабости системы типов!

Принято считать, что интерфейсы предназначены для моделирования абстракций и обеспечения слабой связанности (loose coupling). Звучит умно, но что это значит?

Что дают интерфейсы?

Наследование моделирует семейство объектов с общим поведением. Интерфейс и абстрактный класс определяет «протокол» этого семейства, а наследники определяют конкретную реализацию. Разные виды предусловий можно спрятать за интерфейсом IPrecondition, разные виды стратегий сортировки – за ISorter, разные виды импортеров/экспортеров – за Importer/Exporter.

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

четверг, 27 ноября 2014 г.

DI vs. DIP vs. IoC

Существует три схожих понятия, связанных передачей и управлением зависимостями, в каждом из которых есть слово “инверсия” (inversion) или “зависимость” (dependency):

  • IoC – Inversion of Control (Инверсия управления)
  • DI – Dependency Injection (Внедрение зависимостей)
  • DIP – Dependency Inversion Principle (Принцип инверсии зависимостей)

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