All Projects → savonarola → elixir-basic-patterns

savonarola / elixir-basic-patterns

Licence: other
Материалы ко внутреннему митапу в FunBox, посвященному проблемам в коде новичков в Erlang/Elixir

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to elixir-basic-patterns

OpenU-IntroToJava
מבוא למדעי המחשב ושפת ג'אווה
Stars: ✭ 19 (+35.71%)
Mutual labels:  begginers
competetive-code-hacktoberfest
For Hacktoberfest Contribution
Stars: ✭ 14 (+0%)
Mutual labels:  begginers

Стиль

Говнокод

Условный пример: bad_looking_code.ex. Код, выглядящий так даже издалека, всегда плох. В нем:

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

В таком коде всегда будут плодиться ошибки.

Возврат Ok/Error

Возврат {:ok, ok_result} и {:error, error} -- это стандарт. Положительный и отрицательный результаты должны легко матчиться для возможности просто использовать эмуляцию монады Maybe или Either через with.

Примеры: error_return.ex.

Exceptions vs errors

Не стоит использовать Exceptions для контроля бизнес логики. Это усложняет тип функций, лишает возможности его описать.

Exceptions -- это возможность нормально сообщить, почему код все бросает и падает.

exceptions.ex

Dependency Injection

Два фетчера:

В первом изпользуемый HTTP клиент захардкожен, во втором передается.

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

Тест второго модуля специфицирует реальный контракт с модулем.

Dependency Injection времени

При работе с таймаутами лучше не использовать таймеры. Это сложный внешний state, за которым приходится следить и который трудно тестировать.

Для некритичных к идеальной точности таймеров удобно использовать tick, посылку текущего времени самому себе с указанным интервалом: rotating_file_writer.ex.

Тогда state таймеров превращается в обыкновенный конечный автомат, который легко тестировать извне.

Пример: smpp_timers.ex -- сложная композиция из четырех таймеров SMPP. В oserl реализована с багами через установку и отмену таймеров.

Простейшие паттерны/антипаттерны параллельности

  • Антипаттерн: синхронные операции в "общем" GenServer: good_fetcher.ex. При глобальном использовании представляет из себя бутылочное горлышко.
  • Антипаттерн: возможная неявная синхронизация во внешней либе (HTTPoison) даже при наличии пула. Бутылочное горлышко может быть спрятано и во внешней либе.

Организация последовательной обработки

  • chain_flow_procs.ex -- Плохо. Event кидается от процесса к процессу. Неконтролируемая нагрузка, низкая/неконтролируемая параллелность, неконтролируемая емкость системы.
  • chain_flow_funs.ex -- Не так плохо, но тоже плохо. Event кидается из функции в функцию, сложно отслеживать и расширять поток.
  • direct_flow.ex -- Хорошо. Свой поток выполнения для каждого Event'а, неважно, что из себя представляют обработчики, можно легко измерить статистику по каждой стадии обработки, легко управлять стадиями.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].