Можно обойтись и без композиции, например отедльную абстракцию сделать под отправку письма, где каждое вложение будет проверяться отдельно. Думаю это будет +/- так выглядеть
type Attachment interface {
IsApproved() bool
Type() string
}
type LetterService struct {
attachments AttachmentRepository
}
func (s *LetterService) SendLetter(l *Letter) error {
atts := s.attachments.GetAttachmentsForLetter(l.ID())
for _, a := range atts {
if !a.IsApproved() {
return fmt.Errorf("attachment %s not approved", a.Type())
}
}
//...
return nil
}
Как на Go будет выглядеть модель данных, которая не даст использующему её программисту сломать инвариант?
type Document struct {
id string
status documentStatus
}
type Letter struct {
id string
status letterStatus
document *Document
}
В целом можно примерно так сделать, для простоты в одном пакете разместил. В случае который вы описали, логичнее всего добавить к письму информацию о документе, ниже то как работа будет выглядеть с точки зрения обычного программиста в комментах вывод
func main() {
doc := NewDocument("doc-1")
letter := NewLetter("letter-1")
letter.AttachDocument(doc)
err := letter.Send()
fmt.Println("1. Send:", err)
doc.Approve()
err = letter.Send()
fmt.Println("2. Send:", err)
err = letter.Send()
fmt.Println("3. Send again:", err)
}
/*
1. Send: attached document is not approved
2. Send: <nil>
3. Send again: letter already sent
*/
полный код (ряд моментов упростил но как пример думаю подойдет)
Ну вот смотрите, у вас почти по всем пунктам ответы: "есть но урезано", "не так красиво"
Так мы же и рассматривали минусы, я же сразу отметил что в целом в го подход к разработке отличается от c#/java. Изначально язык проектировался так, чтобы уйти от большого количества абстракций, и быть ближе к разрабам на C.
Если мне инструмент сначала нужно самому допиливать под довольно типовые задачи энтерпрайза
Можете конкретный пример привести, я говорил только про то что "можно" самому дописать, а можно взять готовое(для многих в го не проблема написать типовую функцию для работы с коллекцией) кому что удобнее
Если домен сложный (в энтерпрайзе это часто), то для описания его поведения нужна сложная система типов.
Тут тоже услышать бы реальный пример, на го вполне успешно написаны сложные инструменты типа докера, кубернетеса, терраформ, в банковской сфере есть Monzo да и многие компании используют го
Вот в DDD один из корневых принципов это изоляция доменных моделей и агрегатов от слоя приложения, как гошники решают эту проблему?
Если кратко то через интерфейсы и пакеты.
В целом больштнство современных проектов вы можете писать без какой-то боли. Но писать на нём так как в C#/Java, то вы вероятно встретите негативную реакцию. Т.к. просто другой подход в языке используется.
P.S. Вы написали много про проблемы, поэтому хотелось бы услышать реальный пример на уровне фичи или бизнес задачи
На самом деле в го просто немного другой подход к программированию, который отличается от принятых например в C#/Java и также важно понимать, что го используется для более узкого круга задач и изначально проектировался как более простой и прозрачный язык, хотел бы немного обсудить ваши тезисы:
Нет ООП - в привычных терминах ООП скорее урезано, интерфейсы работают проще и наследования нет, вместо него используют встраивание. Тут лично мой опыт, но его практически всегда достаточно, даже в крупных проектах(я имею ввиду те, что пишут на го).
нет перегрузки - её нет, но если что-то похожее нужно то вполне можно заменить при помощи Functional Options Pattern, будет одна функция, в которую вы сможете передавать разные параметры, опять же код будет посложнее, но в целом это не прям проблемно вроде
нет ко-контравариантности, тут я так понимаю подразумеваются также и ковариативность и т.д., тут опять же в таком виде как в Java их нет, но если такое поведение реально нужно в проекте его можно добиться, хотя оно конечно будет реализовано не так красиво
нет встроенных инструментов для работы с коллекциями - прям встроенных вроде нет (только для базовых типов, что-то есть) но после ввода дженериков можно либо что-то готовое использовать либо самому написать, да там есть ряд ограничений, но не сказал бы что на практике это реально часто мешает (опять же го проекты) да и для большинства задач это хватит.
не понимаю, как на таком языке строить солюшен-архитектуру - тут бы хотелось услышать подробнее, что подразумевается. Вроде СА никак не привязана к языку.
Можно обойтись и без композиции, например отедльную абстракцию сделать под отправку письма, где каждое вложение будет проверяться отдельно. Думаю это будет +/- так выглядеть
В целом можно примерно так сделать, для простоты в одном пакете разместил. В случае который вы описали, логичнее всего добавить к письму информацию о документе, ниже то как работа будет выглядеть с точки зрения обычного программиста в комментах вывод
полный код (ряд моментов упростил но как пример думаю подойдет)
Так мы же и рассматривали минусы, я же сразу отметил что в целом в го подход к разработке отличается от c#/java. Изначально язык проектировался так, чтобы уйти от большого количества абстракций, и быть ближе к разрабам на C.
Можете конкретный пример привести, я говорил только про то что "можно" самому дописать, а можно взять готовое(для многих в го не проблема написать типовую функцию для работы с коллекцией) кому что удобнее
Тут тоже услышать бы реальный пример, на го вполне успешно написаны сложные инструменты типа докера, кубернетеса, терраформ, в банковской сфере есть Monzo да и многие компании используют го
Если кратко то через интерфейсы и пакеты.
В целом больштнство современных проектов вы можете писать без какой-то боли. Но писать на нём так как в C#/Java, то вы вероятно встретите негативную реакцию. Т.к. просто другой подход в языке используется.
P.S. Вы написали много про проблемы, поэтому хотелось бы услышать реальный пример на уровне фичи или бизнес задачи
На самом деле в го просто немного другой подход к программированию, который отличается от принятых например в C#/Java и также важно понимать, что го используется для более узкого круга задач и изначально проектировался как более простой и прозрачный язык, хотел бы немного обсудить ваши тезисы:
Нет ООП - в привычных терминах ООП скорее урезано, интерфейсы работают проще и наследования нет, вместо него используют встраивание. Тут лично мой опыт, но его практически всегда достаточно, даже в крупных проектах(я имею ввиду те, что пишут на го).
нет перегрузки - её нет, но если что-то похожее нужно то вполне можно заменить при помощи Functional Options Pattern, будет одна функция, в которую вы сможете передавать разные параметры, опять же код будет посложнее, но в целом это не прям проблемно вроде
нет ко-контравариантности, тут я так понимаю подразумеваются также и ковариативность и т.д., тут опять же в таком виде как в Java их нет, но если такое поведение реально нужно в проекте его можно добиться, хотя оно конечно будет реализовано не так красиво
нет встроенных инструментов для работы с коллекциями - прям встроенных вроде нет (только для базовых типов, что-то есть) но после ввода дженериков можно либо что-то готовое использовать либо самому написать, да там есть ряд ограничений, но не сказал бы что на практике это реально часто мешает (опять же го проекты) да и для большинства задач это хватит.
не понимаю, как на таком языке строить солюшен-архитектуру - тут бы хотелось услышать подробнее, что подразумевается. Вроде СА никак не привязана к языку.