среда, 12 ноября 2014 г.

Когда предусловия не являются предусловиями

UPDATE: библиотека Code Contract знает о тонкостях реализации таких возможностей как async/await и блоков итераторов. Поэтому описанные ранее проблемы касаются лишь старых (legacy) предусловий, основанных на if-throw. Если вы зашли сюда первый раз, то просто не обращайте внимания на этот абзац!

Что такое предусловие? Это некоторое утверждение, которое должно быть истинным во время вызова метода, причем за его истинность отвечает вызывающая сторона. Предусловия включают в себя проверку аргументов или внутреннего состояния объекта, а его нарушение проявляется в генерации вызываемым кодом исключений ArgumentException для невалидных аргументов, и InvalidOperationException для вызова метода в невалидном состоянии объекта.

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

// class CustomStream
public Task<string> ReadString(int
position)
{
   
if (position < 0
)
       
throw new ArgumentOutOfRangeException("position"
);
   
if
(CanRead)
       
throw new InvalidOperationException("Stream is not readable"
);

   
return Task.FromResult("42");
}

среда, 5 ноября 2014 г.

О логировании исключений и Exception.ToString

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

Очень неприятно, когда тебе приходится разбираться с проблемой на боевом сервере в час ночи, когда все, что ты видишь в логе – загадочную строку “Exception has been thrown by the target of an invocation” или “The type initializer for ‘YourBestTypeInTheWorld’ threw an exception”. А все потому, что кто-то умудрился сохранять в лог не все исключение, а лишь его сообщение.

clip_image002

четверг, 30 октября 2014 г.

О книге “Writing High-Performance .NET Code”

Как-то давно не было рецензий умных книжек, так что пришло время это исправить. Недавно, уважаемый Sinix на rsdn.ru упомянул о книге, с любопытным названием “Writing High-Performance .NET Code”. Я вообще не собирался переключаться пока на литературу по .NET-у, но поскольку по работе мне нужно было пообщаться поближе с виндовыми счетчиками производительности (a.k.a. performance counters), а они были описаны в одной из глав этой книги, то меня как-то зацепило.

clip_image002

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

вторник, 21 октября 2014 г.

четверг, 9 октября 2014 г.

Шпаргалка по SOLID принципам

S – The Single Responsibility Principle

Название: Принцип единственной ответственности.

Определение: У класса/модуля должна быть лишь одна причина для изменения.

Смысл принципа: Борьба со сложностью, важность которой резко возрастает при развитии логики приложения.

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

Типовые примеры нарушения: 1) смешивание логики и инфраструктуры: бизнес-логика смешана с представлением, слоем персистентности, находится внутри WCF или windows-сервисов и т.п. 2) класс/модуль решает задачи разных уровней абстракции: вычисляет CRC и отправляет уведомления по электронной почте; разбирает json-объект и анализирует его содержимое и т.п.

Anti-SRP – Принцип размытой ответственности. Чрезмерная любовь к SRP ведет к обилию мелких классов/методов и размазыванию логики между ними.

четверг, 2 октября 2014 г.

О принципах проектирования

Цикл статей о SOLID принципах

--------------------------------------------------

Для чего выдумывать все эти паттерны проектирования, принципы и методики? Разве не было бы проще обойтись без всего этого, а просто научить разработчиков хорошему дизайну? Или почему бы не формализовать этот процесс и ввести четкие количественные метрики, которые бы говорили, что одно решение однозначно лучше другого?

«Правильный дизайн» - это святой Грааль молодых разработчиков и молодых менеджеров. И те, и другие мечтают найти ответ на главный вопрос жизни, вселенной и всего такого разработки ПО – как добиться качественного дизайна, в сжатые сроки и с минимумом усилий.

Со временем и молодой разработчик, и молодой менеджер придут к пониманию того, что это невозможно. Невозможно найти идеальный абстрактный дизайн, поскольку слова «идеальный» и «абстрактный» противоречат друг другу. Дизайн – это постоянный поиск компромисса между противоречивыми требованиями: производительностью и читабельностью, простотой и расширяемостью, тестируемостью и цельностью решения.

четверг, 25 сентября 2014 г.

The Dependency Inversion Principle

Цикл статей о SOLID принципах

--------------------------------------------------

clip_image001

Принцип инверсии зависимости (Dependency Inversion Principle – DIP):

  • Модули верхнего уровня не должны зависеть от модулей нижнего уровня. И те и другие должны зависеть от абстракций.
  • Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.

Роберт Мартин «Принципы, паттерны и методики гибкой разработки» ([Martin2006]).

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