Обновить
10
Алексей Орлов@lelikPtz

Пользователь

3
Подписчики
Отправить сообщение

основная причина плохого вкуса — это догматичность. Я никогда не буду доверять разработчику, который оправдывает свои решения словами «Это наилучший подход».

Может мне так "везёт", но очень часто сталкиваюсь с противоположной ситуацией, да и на хабре статей на эту тему хватает, когда общепринятые хорошие практики отвергаются и не соблюдаются, так как все эти solid/grasp/чистый код/архитектрура догмы, которым нельзя слепо следовать. Проблем от такого подхода ещё больше.

Можно ли SOLID использовать не правильно? да. Это значит надо учиться правильно применять, вот и всё, отсюда и огромное количество статей, так как это не очень просто.

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

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

Если есть опыт написания тестов и хорошо владеть tdd, то задачи решаются быстрее, чем без них. Сильно экономит время на отладке кода и сразу подсвечивает если что-то сломали "по пути", а не на этапе ручного тестирования/проде.

простота map + RWMutex может быть предпочтительнее

Почему простота? надо правильно написать отдельную обёртку, использовать mutex, понимать разницу RWMutex/Mutex, а sync.Map только тип кастануть при получении.

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

Option pattern удобно и более правильно использовать для установки параметров структуры отличных от дефолтных по умолчанию, например так:

func NewScannedItem(opts ...ScanFunc) *ScannedItem {
	item := &ScannedItem{}
	for _, fn := range opts {
		fn(item)
	}

	return item
}

func WithGS1(value bool) ScanFunc {
	return func(item *ScannedItem) {
		item.GS1 = value
	}
}

func main() {
	NewScannedItem(WithGS1(true))
}

В вашем случае, если в методе Scan надо научиться запускать кастомные валидаторы, то можно в структуру добавить validators []ScanFunc, задавать их список в конструкторе с так же с помощью opts, а в методе Scan вызывать

В том и проблема что можно написать любую функцию, которая будет менять состояние ScannedItem, и будет очень сложно контролировать все возможные варианты, например так:

func (item *ScannedItem) ChangeGS1(value bool) ScanFunc {
	return func(item *ScannedItem) {
		item.GS1 = value
	}
}

и тогда в зависимости от порядка опций в вызове ScannedItem айтем с одними и теме же Datamatrix может быть и валидным и не валидным

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

Если каждый класс реализует интерфейс, а использующие его классы зависят от него, а не от реализации, то:

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

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

Не нарушает, в пункте речь про конфигурацию di, а не код, видимо не очень чётко сформулировал мысль

Очень часто в процессе развития проектов встречал ситуации, когда разработчики докидывают аргументы в существующие реализации, расширяя поведение, при этом не рассматривая альтернативы, так как этот вариант самый дешёвый и простой в конкретный момент времени. А вот с "фанатами правил из книжек" на практике не посчастливилось столкнуться:(

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

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

Информация

В рейтинге
Не участвует
Откуда
Белград, Белград, Сербия
Дата рождения
Зарегистрирован
Активность

Специализация

Backend Developer
Senior
От 250 000 ₽
PHP
OOP
PostgreSQL
Nginx