Рубрика «Проектирование и рефакторинг»

Пулл-реквесты с эмпатией - 1

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

Разработка высококачественных программ сильно зависит от того, насколько качественное ревью кода делают коллеги. Это помогает обнаружить ошибки, избежать двойной работы и в целом обеспечить лучшее качество кода с меньшими усилиями. Код ревью — это критически важная часть процесса разработки.
Читать полностью »

Железнодорожно-ориентированное программирование. Обработка ошибок в функциональном стиле - 1

Как пользователь я хочу изменить ФИО и email в системе.

Для реализации этой простой пользовательской истории мы должны получить запрос, провести валидацию, обновить существующую запись в БД, отправить подтверждение на email пользователю и вернуть ответ браузеру. Код будет выглядеть примерно одинаково на C#:

string ExecuteUseCase() 
{ 
  var request = receiveRequest();
  validateRequest(request);
  canonicalizeEmail(request);
  db.updateDbFromRequest(request);
  smtpServer.sendEmail(request.Email);
  return "Success";
}

и F#:

let executeUseCase = 
  receiveRequest
  >> validateRequest
  >> canonicalizeEmail
  >> updateDbFromRequest
  >> sendEmail
  >> returnMessage

Отклоняясь от счастливого пути

Железнодорожно-ориентированное программирование. Обработка ошибок в функциональном стиле - 2

Дополним историю:

Как пользователь я хочу изменить ФИО и email в системе
И увидеть сообщение об ошибке, если что-то пойдет не так.

Что же может пойти не так?

Железнодорожно-ориентированное программирование. Обработка ошибок в функциональном стиле - 3

  1. ФИО может оказаться пустым, а email – не корректным
  2. пользователь с таким id может быть не найден в БД
  3. во время отправки письма с подтверждением SMTP-сервер может не ответить
  4. ...

Добавим код обработки ошибок

string ExecuteUseCase() 
{ 
  var request = receiveRequest();
  var isValidated = validateRequest(request);
  if (!isValidated) {
     return "Request is not valid"
  }
  canonicalizeEmail(request);
  try {
    var result = db.updateDbFromRequest(request);
    if (!result) {
      return "Customer record not found"
    }
  } catch {
    return "DB error: Customer record not updated"
  }

  if (!smtpServer.sendEmail(request.Email)) {
    log.Error "Customer email not sent"
  }

  return "OK";
}

Вдруг вместо 6 мы получили 18 строк кода с ветвлениями и большей вложенностью, что сильно ухудшило читаемость. Каким будет функциональный эквивалент этого кода? Он выглядит абсолютно также, но теперь в нем есть обработка ошибок. Можете мне не верить, но, когда мы доберемся до конца, вы убедитесь, что это действительно так.
Читать полностью »

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

Определение

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

Пример

Lazy<T> — обертка для объекта, чье создание откладывается до первого обращения к нему.

Антипример

Синглтон — класс, не допускающий создания более одного экземпляра. В этом описании нет союзов, но оно неполное — синглтон всегда имеет основную функциональность помимо контроля единственности собственного экземпляра. Синглтон — класс, реализующий полезную функциональность и контролирующий единственность собственного экземпляра. Теперь описание исчерпывающее, но имеет союз "и" — у синглтона два разных назначения. Он не соответствует принципу единственной ответственности.

Еще антипример

Локатор сервисов — позволяет получить доступ к любому сервису приложения. Это описание без исчерпывающего списка сервисов заведомо неполное.

Назначение

Упрощение создания, анализа и модификации программных систем.

Читать полностью »

image
В этой статье в качестве примера у нас будет программа чуть посложнее, а именно — торговый автомат, реализация которого часто встречается в качестве тестового задания до собеседования. Будут рассмотрены взаимодействие нескольких View с одним VM и наоборот, будет показан подход «View first» и будет показан не итоговый код, с рассказом какая часть для чего нужна (ссылка для скачивания кстати Vending Machine (программный код)), а будет продемонстрирован весь процесс создания и, самое главное, последовательный ход мысли.

Но перед этим я постараюсь еще раз ответить на вопрос, который обычно не задают люди, имеющие опыт отладки неструктурированных проектов, а именно: «Так зачем все-таки нужен паттерн MVVM?»

Если формально и коротко, то паттерн MVVM используется в первую очередь для разделения ответственности, для повышения читабельности, управляемости, поддерживаемости и тестируемости кода. Программный продукт состоит из модели (доменной модели и бизнес-логики) и инфраструктурного кода в соотношении, допустим, 20% на 80%. Инфраструктурный код должен быть простым, понятным, чуть ли не автоматным — как Scaffolding. А вот модель…
Читать полностью »

Монады используются для компоновки функции (function composition) и избавления от связанного с этим утомительного однообразия. После семи лет программирования на Go необходимость повторять if err != nil превращается в рутину. Каждый раз, когда я пишу эту строку, я благодарю Gopher’ов за читабельный язык с прекрасным инструментарием, но в то же время проклинаю за то, что чувствую себя наказанным Бартом Симпсоном.

Монады для Go-программистов - 1

Читать полностью »

В настоящей статье задействован мой опыт доведения некоторого числа студентов до полного и окончательного понимания паттерна MVVM и реализации его в WPF. Паттерн описывается на примерах возрастающей сложности. Сначала теоретическая часть, которая может использоваться безотносительно конкретного языка, затем практическая часть, в которой показано несколько вариантов реализации коммуникации между слоями с использованием WPF и, немножко, Prism.

Зачем вообще нужно использовать паттерн MVVM? Это ведь лишний код! Написать тоже самое можно гораздо понятнее и прямолинейнее.

Отвечаю: в маленьких проектах прямолинейный подход срабатывает. Но стоит ему стать чуть больше — и логика программы размазывается в интерфейсе так, что потом весь проект превращается в монолитный клубок, который проще переписать заново, чем пытаться распутать. Для наглядности можно посмотреть на две картинки:
Читать полностью »

Одним из параметров оценки кода служит его чистота. Создатель языка моделирования UML Гради Буч (Grady Booch) писал:

«Чистый код прост и ясен. Чистый код читается как хорошо написанное произведение. Чистый код никогда не скрывает намерений создателя, но, напротив, полон четких абстракций и простых линий передачи управления»

Сегодня мы собрали для вас список книг и статей по этой теме, которые рекомендуют к прочтению резиденты Hacker News, Stack Exchange и других профильных платформ.

Литература на выходные: 15 материалов по структурированию кода для разработчиков - 1Читать полностью »

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

До недавнего времени такой взгляд на вещи действительно был недалек от истины: говорим ФП, подразумеваем Хаскель и теорию категорий. В последнее время ситуация изменилась и функциональная парадигма набирает обороты в web-разработке, не без помощи F#, Scala и React. Попробуем взглянуть на «паттерны» функционального программирования, полезные для решения повседневных задач с точки зрения ООП – парадигмы.

ООП широко распространено в разработке прикладного ПО не одно десятилетие. Все мы знакомы с SOLID и GOF. Что будет их функциональным эквивалентом?.. Функции! Функциональное программирование просто «другое» и предлагает другие решения.

«Паттерны» функционального программирования - 2
Читать полностью »

В минувшее воскресенье Sam Brannen анонсировал выход JUnit 5! Ура!
10 интересных нововведений в JUnit 5 - 1

Поздравляю всех участников @JUnitTeam а также всех, кто использует JUnit в своей работе! Давайте посмотрим, что же нам приготовили в этом релизе.Читать полностью »

Программирование — достаточно молодая область знаний, однако, в ней уже существуют базовые принципы «хорошего кода», рассматриваемые большинством разработчиков как аксиомы. Все слышали о SOLID, KISS, YAGNI и других трех- или четырех- буквенных аббревиатурах, делающих ваш код чище. Эти принципы влияют на архитектуру вашего приложения, но помимо них существуют архитектурные стили, методологии, фреймворки и много чего еще.

Разбираясь со всем этим по отдельности, меня заинтересовал вопрос — как они взаимосвязаны? Пытаясь выстроить иерархию и вдохновившись небезызвестной пирамидой Маслоу, я построил свою пирамиду «архитектуры приложения».

О том, что из этого вышло — читайте под катом.
Читать полностью »