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

image

Однажды днем у нас обрушился сайт. Сразу после ребута он падал снова. Мы знали, что это не DDOS, а органический трафик: к нам поступали типичные запросы, но сервера не справлялись. Увеличение мощности железа не помогало. Стало ясно, что пора оптимизировать нашу систему.

Молодым стартапам может быть интересно, как справляться с возросшими нагрузками на еще неокрепшее серверное ПО.

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

Во всём виноват PHP OPCache? - 1

Когда я начинал карьеру разработчика, то очень удивился, прочитав фразу, которую приписывают Филу Карлтону (Phil Karlton): «В информатике есть лишь две сложности: инвалидация кеша и присвоение имён». Я отнёсся к этому недоверчиво, поскольку не понял сути фразы. Но немного позже я начал понимать.

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

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

Рад объявить о первом крупном обновлении глобальной тепловой карты в Strava Labs c 2015 года. Это обновление включает в себя в шесть раз больше данных, чем раньше —  в сумме 1 миллиард активностей со всей базы Strava по сентябрь 2017 года.

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

  • 1 миллиард активностей
  • 3 триллиона точек долготы/широты
  • 13 триллионов пикселей после растрирования
  • 10 терабайт исходных данных
  • Общая дистанция маршрутов: 27 миллиардов километров
  • Запись общего времени активности: 200 тысяч лет
  • 5% земной суши покрыто тайлами

Глобальная теплокарта Strava: теперь в 6 раз горячее - 1
Тепловая карта Москвы демонстрирует функцию поворота/наклона в Mapbox GL
Читать полностью »

Шаблон проектирования «состояние» двадцать лет спустя - 1 Состояние — поведенческий шаблон проектирования. Используется в тех случаях, когда во время выполнения программы объект должен менять своё поведение в зависимости от своего состояния. Классическая реализация предполагает создание базового абстрактного класса или интерфейса, содержащего все методы и по одному классу на каждое возможно состояние. Шаблон представляет собой частный случай рекомендации «заменяйте условные операторы полиморфизмом».

Казалось бы, все по книжке, но есть нюанс. Как правильно реализовать методы не релевантные для данного состояния? Например, как удалить товар из пустой корзины или оплатить пустую корзину? Обычно каждый state-класс реализует только релевантные методы, а в остальных случаях выбрасывает InvalidOperationException.

Нарушение принципа подстановки Лисков на лицо. Yaron Minsky предложил альтернативный подход: сделайте недопустимые состояния непредставимыми (make illegal states unrepresentable). Это дает возможность перенести проверку ошибок со времени исполнения на время компиляции. Однако control flow в этом случае будет организован на основе сопоставления с образцом, а не с помощью полиморфизма. К счастью, частичная поддержка pattern matching появилась в C#7.
Читать полностью »

Все мы так или иначе используем открытый код в своей работе, будь то IDE или браузер, системные утилиты или даже скрипты на сайтах. Суть и прелесть опенсорса в том, что каждый желающий может вносить свой вклад в такие проекты. Однако на деле не каждый знает, как это правильно сделать или просто боится начать.

Мы и наша технологическая лаборатория Exantech поддерживаем open source и хотим сделать участие в нем более популярным среди разработчиков.

28 октября в московском «Ключе» мы проведем свой Code Jam в рамках Hacktoberfest — ежегодного онлайн-фестиваля по программированию в open source от Digital Ocean.

image

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

Как мы Raiffeisen Online создавали… - 1

Интернет-банк уже давно превратился из роскоши в must have для любого уважающего себя банка. Излишне говорить, что приложение должно не просто быть, а должно быть надёжным, удобным и приятным в использовании. В одной статье не получится рассказать обо всех аспектах нашего интернет-банка Raiffeisen Online, но зато я расскажу о нашем опыте создания новой версии, его архитектуре и трудностях, с которыми столкнулась команда. Возможно, кому-то наш опыт поможет сэкономить время и усилия.
Читать полностью »

Одним из главных аспектов при разработке программного обеспечения вообще и web-приложений в частности я считаю способность программного обеспечения быть изменяемым — адаптируемым к изменениям окружающего мира. Это не значит, что разработчик должен заранее предусмотреть будущие изменения среды обитания своего кода, это значит, что код должен переносить множество циклов рефакторинга, оставаясь при этом работоспособным как можно дольше. А для этого нужно, чтобы последствия изменений, вносимых в код, были либо обозримы, либо предсказуемы. Под катом я суммировал свое понимание областей сокрытия кода, сформировавшееся в результате тесных, практически интимных, отношений с Magento 2 (платформой для построения интернет-магазинов). Изложенное ниже относится во-первых, к языку PHP, во-вторых — к web-приложениям, в-третьих — ко всему остальному.

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

Пулл-реквесты с эмпатией - 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> — обертка для объекта, чье создание откладывается до первого обращения к нему.

Антипример

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

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

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

Назначение

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

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


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js