Можно ли SOLID использовать не правильно? да. Это значит надо учиться правильно применять, вот и всё, отсюда и огромное количество статей, так как это не очень просто.
Не умение их применять очень удобно списывать на "солид переоценён", "солид не догма", "именно в моей задаче он не нужен" и тд
Имхо, очень часто встречаются ведь как раз обратные приведённым примерам ситуации - код написанный вообще без оглядок на всякие правила. И он тоже вызывает огромное количество проблем.
Если есть опыт написания тестов и хорошо владеть tdd, то задачи решаются быстрее, чем без них. Сильно экономит время на отладке кода и сразу подсвечивает если что-то сломали "по пути", а не на этапе ручного тестирования/проде.
простота map + RWMutex может быть предпочтительнее
Почему простота? надо правильно написать отдельную обёртку, использовать mutex, понимать разницу RWMutex/Mutex, а sync.Map только тип кастануть при получении.
Выглядит будто sync.Map удобней использовать по дефолту даже при небольшом количестве горутин и операций: проще написать, меньше шансов ошибиться, потокобезопасно по умолчанию.
В вашем случае, если в методе Scan надо научиться запускать кастомные валидаторы, то можно в структуру добавить validators []ScanFunc, задавать их список в конструкторе с так же с помощью opts, а в методе Scan вызывать
В том и проблема что можно написать любую функцию, которая будет менять состояние ScannedItem, и будет очень сложно контролировать все возможные варианты, например так:
Паттерн крутой, но так он меняет cостояние объекта, применяя его в методах структуры стреляете себе в ногу, например необходимо сбрасывать значения полей при повторных вызовах.
Если каждый класс реализует интерфейс, а использующие его классы зависят от него, а не от реализации, то:
1) Легче писать тесты замокав эти интерфейсы. 2) По мере развития кода очень просто на основе контракта, описанного в интерфейсе, подменить реализацию на новую или использовать несколько разных реализаций.
Как и везде есть исключения, но как мне кажется доказывать надо именно их необходимость в конкретных случаях, а в общем случае лучше интерфейс
Очень часто в процессе развития проектов встречал ситуации, когда разработчики докидывают аргументы в существующие реализации, расширяя поведение, при этом не рассматривая альтернативы, так как этот вариант самый дешёвый и простой в конкретный момент времени. А вот с "фанатами правил из книжек" на практике не посчастливилось столкнуться:(
Предложенное ограничение заставляет задуматься об альтернативах. И само собой бывают исключения.
Не хотелось очень подробно расписывать обоснования каждого пункта, так как отдельно это обсуждалось много раз и решил попробовать изложить как можно короче, видимо не очень получилось, наброс принят)
Можно ли SOLID использовать не правильно? да. Это значит надо учиться правильно применять, вот и всё, отсюда и огромное количество статей, так как это не очень просто.
Не умение их применять очень удобно списывать на "солид переоценён", "солид не догма", "именно в моей задаче он не нужен" и тд
Имхо, очень часто встречаются ведь как раз обратные приведённым примерам ситуации - код написанный вообще без оглядок на всякие правила. И он тоже вызывает огромное количество проблем.
Если есть опыт написания тестов и хорошо владеть tdd, то задачи решаются быстрее, чем без них. Сильно экономит время на отладке кода и сразу подсвечивает если что-то сломали "по пути", а не на этапе ручного тестирования/проде.
Почему простота? надо правильно написать отдельную обёртку, использовать mutex, понимать разницу RWMutex/Mutex, а sync.Map только тип кастануть при получении.
Выглядит будто sync.Map удобней использовать по дефолту даже при небольшом количестве горутин и операций: проще написать, меньше шансов ошибиться, потокобезопасно по умолчанию.
Option pattern удобно и более правильно использовать для установки параметров структуры отличных от дефолтных по умолчанию, например так:
В вашем случае, если в методе Scan надо научиться запускать кастомные валидаторы, то можно в структуру добавить validators []ScanFunc, задавать их список в конструкторе с так же с помощью opts, а в методе Scan вызывать
В том и проблема что можно написать любую функцию, которая будет менять состояние ScannedItem, и будет очень сложно контролировать все возможные варианты, например так:
и тогда в зависимости от порядка опций в вызове ScannedItem айтем с одними и теме же Datamatrix может быть и валидным и не валидным
Паттерн крутой, но так он меняет cостояние объекта, применяя его в методах структуры стреляете себе в ногу, например необходимо сбрасывать значения полей при повторных вызовах.
Если каждый класс реализует интерфейс, а использующие его классы зависят от него, а не от реализации, то:
1) Легче писать тесты замокав эти интерфейсы.
2) По мере развития кода очень просто на основе контракта, описанного в интерфейсе, подменить реализацию на новую или использовать несколько разных реализаций.
Как и везде есть исключения, но как мне кажется доказывать надо именно их необходимость в конкретных случаях, а в общем случае лучше интерфейс
Не нарушает, в пункте речь про конфигурацию di, а не код, видимо не очень чётко сформулировал мысль
Очень часто в процессе развития проектов встречал ситуации, когда разработчики докидывают аргументы в существующие реализации, расширяя поведение, при этом не рассматривая альтернативы, так как этот вариант самый дешёвый и простой в конкретный момент времени. А вот с "фанатами правил из книжек" на практике не посчастливилось столкнуться:(
Предложенное ограничение заставляет задуматься об альтернативах. И само собой бывают исключения.
Не хотелось очень подробно расписывать обоснования каждого пункта, так как отдельно это обсуждалось много раз и решил попробовать изложить как можно короче, видимо не очень получилось, наброс принят)