Search
Write a publication
Pull to refresh
4
0.2
Send message

Раз уж это гайд на пакет - имеет смысл добавить пару слов и о .gitattributes.
В него стоит добавить директории и файлы, которые не нужно распространять с пакетом - тесты, фыйлы конфигов, докерфайлы, ci/cd и прочее, что не нужно конечному пользователю.

Пример можно подсмотреть в почти любом распространнённом php-пакете:

В коде всё конкретно. Код либо работает, либо нет.

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

Как всё просто и конкретно)

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

Вот к примеру слово 'Регистрозависимость', можно написать 32 разными способами просто подменяя кирилические буквы 'o' и 'c'.

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

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

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

Для случаев, когда как в примере из пункта #4, часть аргументов конструктора опциональны, но при этом обязывает наличие другого опционального параметра - делаю конструктор приватным, и создаю два публичных фабричных метода один из которых требует обязательную передачу обоих связанных аргументов, а второй не предполагает их передачи вовсе. Это если эти варианты вызываются при разных сценариях. Если комбинаций куда больше, либо язык не предусматривает таких конструкция - обьединяю связанные аргументы в одну структуру, даже если это требуется всего в одном месте

Интерфейсы, если простыми словами, нужны для передачи/получения определенных данных от разных источников

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

Докину еще вариант в тред обсуждения самовалидируемости сущностей и необходимости подключения репозитория для проверки уникальности email.
Я для себя решил эту дилему перестав называть юзера с дублирующим email невалидным.
Юзер валидный, но его сохранение приведет систему к невалидному состоянию чего мы и пытаемя избежать.
Это же касается других правил которые нельзя првоерить в рамках одной сущности\агрегата.

Мы такую проблему решаем вынося всю логику касающуюся более чем одной сущности в доменные сервисы.

Но я бы делал не просто сервис проверки уникальности Email, а сразу сервис создания юзера, который бы проверял наличие дублей в репозитории еще до создания самой сущности.

<?php

class CreateUserService
{
      UserRepositoryInterface repository

      handle(string name, string password, string email)
      {
            # У нас нет никакой необходимости получать юезра из репозиятория, достаточно спросить о его существовании
            if (repository.containtUserWith(email)) {
                  throw new BusinessException.EmailIsNotUnique();
            }

            usersRepository.save(new User(request.Name, request.Password, request.Email));
      }
}

Что мне определенно не нравится в предложенном варианте c ивентами:

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

  • Доменный ивент содержит невалидную сущность.

К примеру захотев отправить юзеру email-нотификашку о регистрации, логично бьло бы делать это в ответ на доменное событие создания юзера, но у нас этот ивент не является свидельством создания юзера, а лишь свидетельством попытки.

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

DDD не запрещает сделать email уникальным на уровне базы для подстраховки, но наличие проверки в коде позволит:

  • Оставить описание требований к этой уникальности в доменном слое приложения.

  • Проведя явную проверку вернуть пользователю ошибку о нарушении конкретного правила, а не отлавливать исключения из базы и пытаться понять что же это за исключение и как обьяснять его пользователю.

Хотелось бы поблагодарить автора за авторскую статью с примерами кода.
Приятно натыкатся на хабре на что-то-то помимо копирайтерского треша и корявых переводов.
Добавить бы еще подстветку PHP-шного синтаксиса в во вставки кода.

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

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

Видимо у нас разные понятия о сущностях или тестах.

В моем понимании сущность это Data Mapper + Rich Domain Model в которую помещается вся бизнес-логика для реализации которой не труебуется взаимодействие с другими сервисами. Таким образом ни для её создания ни для вызова её методов никакие другие сервисы не нужны, и тестировать её можно простым Unit-тестом.

Отдельно тестировать бизнес-логику, не тестируя сущности зачастую гораздо проще. Хотя-бы просто потому, что тестируется только изолированная часть логики.

Для тестирования бизнес-логики размещенной в сущности необходимо:

  • Экземпляра сущности.

Для тестирования бизнес-логики размещенной в сервисе необходимо:

  • Экземпляр сервиса.

  • Зависимости сервиса, либо их моки.

  • Экземпляра сущности или её мок.

И в чем тут простота?

new Length(['max' => $max]),

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

Ctrl-Click по названию метода/переменной

Ctrl + B

И чем можно заменить банальный скрол мыши?

Alt + ↓ \ Alt + ↑ неплохо помогают

А я хоть где-то упоминал про полный отказ от мышки?

Отказался я от нее прежде всего при навигации между файлами\папками.
Если подходить к именованию классов и структуре проекта системно - мне куда проще через Ctrl + Shift + N ввести название класса либо его аббревиатуру, чем перемещаться к нему через древо каталогов. И чем больше проект тем более такой подход мне кажется комфортнее.

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

всего-то инструмент интерфейс поменял

В котором до сих пор ломается что-то что отлично работает в старом интерфесе.

если вы ими уже пользуетесь, то переход становится в разы проще

Или сложнее. У меня регулярно перестают работать хоткеи перехода в пункты меню через Alt + {FirstLetter}, в итоге вместо отрытия меню Git нажатием Alt + G, мне приходится перебирать хоткеи других пунктов и уже после нахождения работающего переходить в Git.

Начну с того что не пытаюсь никого переубедить в том кому как удобней. Вопрос привычек, предпочтений и опыта работы с конкретной конфигурацией.

Вам это удобнее?

Да. Я никогда эти шорткаты не заучивал. Увидел -> решил что это удобней чем навигация мышкой -> начал использовать. Пол года назад обнаружил что табы вообще не использую и выключил их.

Вместо 1 клика мышкой с минимальной когнитивной нагрузкой

Вместо того чтобы тянутся к мышке, а потом обратно, я жму клавиши которые вот уже под руками. Когнитивной нагрузки это создает не больше чем нажать F для очередного foreach.

Ctrl + E открывает похожий список с возможность фильтрации по названию.
Тоже отказался от табов в пользу Ctrl + N \ Ctrl + E \ Ctrl + Tab \ Ctrl + Alt + Right \ Ctrl + Alt + Left

1

Information

Rating
5,333-rd
Location
Украина
Date of birth
Registered
Activity