Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[РИТ 2020] Код, с которым приятно иметь дело

[РИТ 2020] Код, с которым приятно иметь дело

Я хотел бы предложить авторам OSS-библиотек и разработчикам приложений взглянуть на написание кода с другой стороны — со стороны тех, кому придётся работать с ним в будущем. Несмотря на то, что чисто технически мы пишем код для машин, его основными пользователями являются люди. Что же такое «код, удобный в использовании»?

За годы работы над коммерческими и OSS-проектами я сформировал для себя список принципов, которыми должен соответствовать такой код, например: тестируемость, гибкость, расширяемость, узнаваемость и т.д. В докладе я рассмотрю этот «чек-лист» подробнее, а также приведу примеры из мира Руби и не только.

Vladimir Dementyev

May 26, 2020
Tweet

More Decks by Vladimir Dementyev

Other Decks in Programming

Transcript

  1. palkan_tula palkan Кот, с которым приятно иметь дело Что это?

    Д Если код хорош — то всегда легко, а когда наоборот — трудно
  2. palkan_tula palkan Простой код 21 Минимум кода для простого функционала

    Меньше думать при написании Легко понимать написанное
  3. palkan_tula palkan 24 var req = new XMLHttpRequest(); req.responseType =

    'json'; req.onload = function() { handle(xhr.response) }; req.open('GET', '/api/me.json', true); req.send(null);
  4. palkan_tula palkan 26 uri = URI("http: //example.com/index.json") params = {limit:

    10, page: 3} uri.query = URI.encode_ www_form(params) req = Net ::HTTP ::Get.new uri req.basic_auth 'user', 'pass' res = Net ::HTTP.start(uri.host, uri.port) do |http| http.request(req) end if res.is_a?(Net ::HTTPSuccess) JSON.parse(res.body) end
  5. palkan_tula palkan Разумная конфигурация 34 Значения, которые подходят большинству пользователей

    Автоматическое «распознавание» популярных переменных окружения (DATABASE_URL, REDIS_URL)
  6. palkan_tula palkan 36 SomeSDK.configure do |config| config.access_key = "REPLACE_WITH_ACCESS_KEY_ID" config.secret_key

    = "REPLACE_WITH_SECRET_ACCESS_KEY" end Разумная конфигурация В документации каждой второй библиотеки для интеграции с API
  7. palkan_tula palkan Разумные соглашения 41 class Post < ActiveRecord ::Base

    belongs_to :user end Post.joins(:user).all # => SELECT * FROM posts INNER JOIN users ...
  8. palkan_tula palkan 42 class Post < ActiveRecord ::Base self.table_name =

    "posts" belongs_to :user, foreign_key: :user_id, class_name: "User", primary_key: :id end Разумные соглашения
  9. palkan_tula palkan Простой код 43 Минимум кода для простого функционала

    Меньше думать при написании Легко понимать написанное
  10. palkan_tula palkan Wat, Ruby?! 45 1.nonzero? # => 1 0.nonzero?

    # => nil 0.zero? # => true 1.zero? # => false
  11. palkan_tula palkan Erlang :( 47 1> lists:split(2, [2, 0, 2,

    0]). {[2,0],[2,0]} 2> lists:sublist(2, [2, 0, 2, 0]). ** exception error: no function clause matching 3> lists:sublist([2, 0, 2, 0], 2). [2, 0]
  12. palkan_tula palkan Минимум wtf 50 Консистентность API и стиля кода

    Узнаваемость/похожесть/подражание Отсутствующие/осмысленные monkey patches Однозначные именования
  13. palkan_tula palkan Синтаксический уксус 53 Заставляет разработчика задуматься о том,

    что он делает Намекает на потенциальную опасность операции
  14. palkan_tula palkan Сообщения об ошибках 59 Содержательные: содержат максимум контекста

    для быстрой локализации проблемы Призывающие к действию: содержат инструкции для устранения проблемы
  15. palkan_tula palkan Содержательные ошибки 60 # плохо create_event(type: "BBQ") =>

    Unknown type. # хорошо create_event(type: "BBQ") => Unknown type: BBQ.
  16. palkan_tula palkan Ошибки с подсказками 61 # плохо create_event(type: "BBQ")

    => Unknown type. # хорошо create_event(type: "BBQ") => Unknown type: BBQ. # отлично create_event(type: "BBQ") => Unknown type: BBQ. Choose: quarantine or self- isolation"
  17. palkan_tula palkan Логирование 65 Должно помогать, а не мешать Должно

    быть настраиваемым (уровни, формат, устройство вывода)
  18. palkan_tula palkan Логирование 67 Должно помогать, а не мешать Должно

    быть настраиваемым (уровни, формат, устройство вывода) Должно иметь разумные настройки по умолчанию
  19. palkan_tula palkan Удобно ли тестировать код, который использует ваш код,

    или код, который использует код, которой использует ваш код, или код, который использует код, который использует код, которой использует ваш код... 70
  20. palkan_tula palkan 72 # Тестовые адаптеры config.active_job.queue_adapter = :test config.action_mailer.delivery_method

    = :test # Мок-режим Fog.mock! # No-op режим Sidekiq ::Testing.fake! Тестируемость
  21. palkan_tula palkan 75 CarrierWave.configure do |config| config.enable_processing = false end

    Devise.setup do |config| config.stretches = Rails.env.test? ? 1 : 11 end Тестируемость
  22. palkan_tula palkan Документация (в широком смысле) — это всё то,

    что в будущем за вас ответит на вопросы разработчиков 80
  23. palkan_tula palkan Документация 81 Непосредственно документы (специально написанные) Комментарии в

    коде Сообщения коммитов / описания PR История изменений (change log) Примеры / демо / тесты
  24. palkan_tula palkan Чек-лист 83 Минимум шаблонного кода Разумные значения по

    умолчанию Интуитивно понятный API Содержательные сообщения об ошибках