kamyshev.code – Telegram
kamyshev.code
1.77K subscribers
40 photos
565 links
Архитектура, код, софт-скиллы и всё остальное. Вопросы, пожелания, комментарии — @igorkamyshev

https://kamyshev.me
Download Telegram
PHP бесит, в частности тем, что встроенные функции не кидают исключения, а возвращают false, 0 или какую-то другую дичь при ошибке.

Крутейшая библиотека, которая решает эту проблему — https://github.com/thecodingmachine/safe

#php
Давно убежден, что технология вторична. Куда важнее уметь разрабатывать программы, чем программировать. Нужно учиться фундаментальным штукам, а не как на реакте формочки делать. И тогда уже не так важно, какой язык или фреймворк используется для решения задачи.

Ну и это позволяет стать чуть более полезным.

Видео о том, как расти разработчику — https://youtu.be/BULiyNTlq8o
Эванс предлагает строить приложения по многоуровневой архитектуре.

1. Представление (Presentation). Работа с внешним источником команд. Это может быть интерфейс пользователя, API. Тут только принимаем запрос и формируем ответ.
2. Операционный (Application). Тут занимаемся оркестрацией объектами доменной модели. Решаем как и куда их дёрнуть.
3. Предметной области (Domain). Вся логика работы приложения. Бизнес правила.
4. Инфраструктурный (Infrastructure). Обеспечение работы других слоев. Общение с базой данных, отправка уведомлений, загрузка файлов на удаленное хранилище.

При этом компоненты слоя могут зависеть только от компонентов находящихся в том же слое, или ниже. То есть Application не может зависеть от Interface, но может от Infrastructure.

#ddd
При разработке React-приложений почти всегда используют Redux.

Но писать редьюсеры — большая неприятность. Куча шаблонного кода, страдает читаемость. Недавно открыл для себя библиотеку, которая полностью решает эту проблему.

https://github.com/atomixinteractions/redux-symbiote

Симбиот — функция принимающая стейт, и пейлоад экшена, возвращающая новый стейт. На выходе получаем набор экшенов и редьюсеров, которые можно использовать как обычно. Удобно!

#js
Важная мелочь для меня в программировании — комфорт от набора текста. Он складывается из темы редактора, шрифта, клавиатуры и много чего ещё, наверно.

Уже несколько лет использую шрифт Fira Code. Во-первых, он крутой. А во-вторых, в нем есть лигатуры.

Лигатуры — это когда несколько логически связанных символов становятся одним. Например, != станет .

На мой взгляд, так код воспринимается много легче.

https://github.com/tonsky/FiraCode

#удобство_разработки
Вернёмся к Эвансу.

Слой предметной области представляет три типа объектов.

1. Сущности — эти объекты уникальные от рождения и до смерти. Например, в контексте банковской сферы, это клиент. Не важно, сменил он имя, пол или адрес. Нам важно сохранить его историю.
2. Объекты-значения — не уникальны, ценны только своим значением. В том же контексте, это могут быть адреса. Адрес однозначно характеризуется городом, улицей, домом. Если что-то из этого изменилось — это уже совсем новый адрес.
3. Сервисы. Кусочки логики не относящиеся к сущностям или объектам-значениям. Например, сервис выполнения транзакций. Он работает сразу с двумя счетами и хранит логику перевода средств с одного на другой.

#ddd
Управлять сущностями и вэлью-обжектами сложно. Потому часто несколько таких объектов объединяют в агрегат. Агрегат управляет всеми объектами внутри себя и наружу представляет только одну сущность. Она называется корневой.

Так как агрегаты сложно строить руками, часто используют фабрики для этого.

А для получения корневой сущности по какому-нибудь принципу — репозиторий.

#ddd
По долгу службы, в скором времени буду строить довольно крупное приложение на NodeJS.

На этой неделе написал технический прототип и познал всю боль с Express. Неудобно, нужно много написать самому. Подумал, что нужно что-то другое. И как раз на митапе несколько дней назад добрый человек посоветовал посмотреть на Nest.js.

И оно выглядит прямо хорошо!

Особенно, меня, как большого любителя TypeScript, порадовала их дружба.

Всем, кто строит хоть сколько-нибудь большие приложения на NodeJS рекомендую посмотреть на это решение. Возможно, оно подойдёт и вам.

https://docs.nestjs.com

#js #ts
​​Проектирование

Разберёмся, что такое инверсия зависимости. Представьте ситуацию, ваша функция использует какую-то другую. И она её берет и вызывает. Все вроде хорошо. Но что если нужно теперь заменить вызываемую функцию на другую? Становиться как-то сложно.

Чтобы сложно не было, можно передать эту функцию как аргумент. Тогда заменить ее будет легко.

Было:
function square(x) {
return power(x, 2)
}


Стало:
function square(x, power) {
return power(x, 2)
}


С одной стороны, кода стало больше. И выглядят он странно. Но на серьезных операциях чувствуются преимущества.

Например, когда нужно подменить логгер. Вдруг, мы больше не хотим писать логи в консоль, а хотим в файл. В подавляющем большинстве приложений без боли сделать это невозможно. А можно было бы.

#проектирование
​​Проектирование

Для инверсии зависимостей важна информация о типах данных.

В прошлом посте был пример с двумя функциями. Если в качестве power передать функцию, которая принимает массив, а возвращает сумму элементов, то и функция square работать перестанет.

Конечно, можно обеспечить порядок с типами написав много тестов. Но ведь это сложно. Проще объявить, что мы ждём функцию, принимающую два числа и возвращающую число. Например, так:

function square(
x: number,
power: (x: number, y: number) => number
) {
return power (x, 2)
}


Мы обезопасим код от многих ошибок.

Это не обязательное условие для реализации инверсии зависимостей. Но так писать надёжные приложения легче.

#проектирование
​​Исследуя GitHub

В функциональном программировании есть удобная концепция Option. Это абстракция над переменной, которой может и не быть (null, undefined, etc.). Она позволяет работать с такими значениями как с коллекцией (пустой, или из одного элемента).

Было:
const parsedInput = !!nullableVar
? parseInt(nullableVar) + 12
: 1

calculate(parsedInput)


Стало:
const parsedInput = optionInput
.map(v => parseInt(v))
.map(v => v + 12)
.getOrElse(1)

calculate(parsedInput)


Теперь представьте, что таких преобразований не одно, а много.

Надавно нашел бибилиотеку для JavaScript/TypeScript, реализующую эту Option.

https://github.com/bcherny/tsoption

#js #ts #fp
​​Проектирование

Относительно функций все сказанное о инверсии зависимостей не слишком часто используется в реальной практике.

Основная область применения этого принципа — объектно-ориентированное программирование.

Если один из ваших классом занимается отправкой уведомлений и для этого ему нужно куда-то послать HTTP запрос, лучше не создавать HTTP-клиент внутри.

Плохо:
class Notificator {
constructor() {
this.httpClient = new HttpClient()
}

notify() {
// do something with this.httpClient
}
}


Хорошо:
class Notificator {
constructor(httpClient) {
this.httpClient = httpClient
}

notify() {
// do something with this.httpClient
}
}


Почему?
+ Для тестов легко передать фейковый клиент.
+ Заменить реализацию HTTP-клиента можно не трогая Notificator.
+ Можно сделать один клиент, раздать его всем желающим и сэкономить на создании.
+ Циклические зависимости разрешать легко.

#проектирование
​​Онлайн-курс

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

Уверен, что это знание сильно помогает писать приложения без удивления.

Отличный бесплатный курс на Stepik. Рассказывают как работает компьютер, немного про ассемблер, как устроены операционные системы.

Наверно, глубокие знания в этих областях нужны очень небольшому количеству программистов. Но иметь общее представление важно всем.

#общие_знания
​​Проектирование

Итак, мы написали весь код передавая зависимости через конструктор. И получили такой клиентский код:
const notificator = new Notificator(
new SmsAdapter(
new HttpClient(),
new Logger(),
),
)


Как этим пользоваться? Никак.

Вместо создания сервисов руками в клиентском коде следует делегировать эту работу кому-нибудь. Например, DI-контейнеру. Эта штука создает все нужные сервисы (на основании какой-то конфигурации) и позволяет получить уже подготовленный сервис в клиентском коде.

const notificator = Container.get(Notifier)

#проектирование
​​Нужная книга

Две недели назад закончил читать "Программиста-фанатика" и готов порекомендовать ее.

Книга совсем не о фанатизме. Оригинальное название "The Passionate Programmer" куда точнее отражает содержание. Она о том, как быть выдающимся программистом. И какую пользу это приносит.

В ней совсем мало про конструирование программ. Большая часть посвящена построению карьеры.

#программист_фанатик
​​Проектирование

Полезно понимать, что такое паттерны проектирования.

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

Возникает логичный вопрос, зачем изучать паттерны? Три причины:
+ Проверенные решения. Если кто-то уже решил проблему, то не нужно городить свой велосипед.
+ Стандартизация кода. Другим людям, знающим паттерны, сразу понятно, что написано.
+ Общий программистский словарь. Быстрее сказать коллеге: "Да зафигач сюда адаптер и не парь мозг!", чем "Ну ты сделай класс, который будет превращать интерфейс вот этой штуки в такой, который подходит вот этой штуке."

Ну и последнее. Не нужно бездумно использовать весь перечень паттернов проектирование. Лучше прочитать, осознать и отложить. Потом начать подмечать в коде места, где один из шаблонов смотрелся бы хорошо. И только спустя время начать их применять. Вдумчиво и осторожно.

#проектирование
​​Мудрость из книги

У созданного прототипа есть три ценности:
+ Клиент посмотрит на какое-то подобие системы и даст обратную связь.
+ Программисты, которым предстоит писать настоящую систему познакомятся с проблемой. Поймут ее на более глубоком уровне.
+ Программисты, которые пишут другие части системы (интерфейс, например) смогут начинать разработку, постепенно переходя от взаимодействия с прототипом к работе с настоящей системой.

Конспект книги Эрика Эванса "Предметро-ориентированное проектирование".

#ddd
​​Проектирование

Для удобства высоколобые мужи разделили паттерны проектирования на три типа:

1. Порождающие. Они заведуют созданием объектов хитрыми способами. Помогают избегать лишних зависимостей.

2. Структурные. Существуют для построения хитрых связей между объектами.

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

Наверное, это классификация — не самое полезное, что нужно знать о проектировании ПО. Но для упорядочивания в голове информации о шаблонах проектирования сгодится.

#проектирование
​​Нужная книга

Программисты часто не слишком думают о чем-то кроме работы. Это не здорово.

"Soft Skills: The Software Developer's Life Manual" концентрируется как раз на этом. Как прожить жизнь и не облажаться.

Не уверен, что это будет полезно абсолютно всем. Но попробовать стоит.

Джон Сонмез рассказывает о кучи интересных штук: от востребованности на рынке труда до раннего выхода на пенсию.

#softskills
​​Мудрость из книги

Любой публичный интерфейс должен быть информативен. Если это интерфейс класса, то любой метод должен своим именем выражать, что он делает. Причем не как, а что.

Никогда не следует раскрывать детали реализации в интерфейсе.

Конспект книги Эрика Эванса "Предметро-ориентированное проектирование".

#ddd
​​Онлайн-курс и Нужная книга

Программист, которые не имеет базовых знаний алгоритмов — странный программист. И уж точно такой разработчик стоит сильно меньше, чем его начитанный коллега.

Где научиться? Три варианта разной степени сложности.

1. Книга "Грокаем алгоритмы". Она простая, дружелюбная к читателю и даёт хорошие базовые знания.
2. Англоязычный платный курс Algorithmic Toolbox от Coursera. Качественный, с крутыми задачами и хорошими лекциями. Кстати, учащиеся могут написать письмо и получить курс бесплатно.
3. Русскоязычный бесплатный курс на Stepik. Не хуже, чем аналогичные от Coursera, даже преподавательский состав похож. Но задач меньше.

#обшие_знания