Композиция вместо наследования
Философия проектирования Go
«Композиция вместо наследования» — бесплатный урок Go Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.
Философия проектирования Go
Go намеренно не поддерживает наследование классов. Идиоматический подход — композиция: создавайте поведение, объединяя небольшие типы и интерфейсы.
Почему не наследование
Глубокие деревья наследования ненадёжны: изменение базового класса непредсказуемо распространяется по всей структуре. Композиция сохраняет связи явными и гибкими.
«Имеет» вместо «является»
Вместо модели «менеджер является сотрудником» смоделируйте «менеджер имеет данные и возможности сотрудника» с помощью встраивания или полей.
package main
import "fmt"
type Employee struct{ Name string }
func (e Employee) Work() string { return e.Name + " works" }
type Manager struct {
Employee
Reports int
}
func main() {
m := Manager{Employee{"Lin"}, 3}
fmt.Println(m.Work(), "-", m.Reports, "reports")
}Программирование через интерфейсы
Определяйте поведение с помощью небольших интерфейсов, а затем принимайте их. Реализации взаимозаменяемы, поэтому их легко заменять или имитировать.
package main
import "fmt"
type Notifier interface{ Notify(msg string) }
type Email struct{}
func (Email) Notify(msg string) { fmt.Println("email:", msg) }
func alert(n Notifier, m string) { n.Notify(m) }
func main() {
alert(Email{}, "deploy done")
}Замена реализаций
Поскольку функция зависит от интерфейса, Вы можете передать любую реализацию, не изменяя функцию.
package main
import "fmt"
type Notifier interface{ Notify(msg string) }
type Email struct{}
type SMS struct{}
func (Email) Notify(m string) { fmt.Println("email:", m) }
func (SMS) Notify(m string) { fmt.Println("sms:", m) }
func alert(n Notifier, m string) { n.Notify(m) }
func main() {
alert(Email{}, "hi")
alert(SMS{}, "hi")
}Объединение поведения
Встраивайте несколько небольших компонентов, чтобы собрать функционально насыщенный тип из независимых частей, которые легко тестировать.
package main
import "fmt"
type Logger struct{}
func (Logger) Log(s string) { fmt.Println("log:", s) }
type Cache struct{ data map[string]string }
func (c Cache) Get(k string) string { return c.data[k] }
type Service struct {
Logger
Cache
}
func main() {
s := Service{Cache: Cache{data: map[string]string{"k": "v"}}}
s.Log("started")
fmt.Println(s.Get("k"))
}Внедрение зависимостей
Передавайте зависимости (как интерфейсы) в конструкторы вместо их жесткого задания. Это применение композиции к связыванию компонентов.
package main
import "fmt"
type Store interface{ Save(s string) }
type MemStore struct{ items []string }
func (m *MemStore) Save(s string) { m.items = append(m.items, s) }
type App struct{ store Store }
func NewApp(s Store) *App { return &App{store: s} }
func main() {
app := NewApp(&MemStore{})
app.store.Save("x")
fmt.Println("saved")
}Преимущество небольших интерфейсов
Чем меньше интерфейс, тем больше типов ему соответствуют и тем легче его тестировать. Чем больше интерфейс, тем слабее абстракция.
Как избежать хрупкого базового класса
Без наследования нет базового класса, который может сломаться. Каждая составная часть развивается независимо, что уменьшает связанность.
Принимайте интерфейсы, возвращайте структуры
Распространенное правило Go: функции принимают интерфейсы (гибкие входные данные) и возвращают конкретные структуры (понятные и удобные выходные данные).
Контрольный список композиции
- Моделируйте «имеет», а не «является»
- Встраивайте небольшие компоненты
- Зависите от небольших интерфейсов
- Внедряйте зависимости
Быстрая проверка
Проверьте свои знания философии композиции.
Итоги
Вы изучили философию композиции в Go.
- Нет наследования: используйте композицию с помощью встраивания и интерфейсов
- Моделируйте «имеет» вместо «является»
- Программируйте через небольшие интерфейсы и внедряйте зависимости
- Принимайте интерфейсы, возвращайте структуры
Часто задаваемые вопросы
Урок «Композиция вместо наследования» бесплатный?
Да — полный текст урока «Композиция вместо наследования» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.
Чему я научусь в уроке «Композиция вместо наследования»?
Философия проектирования Go Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Go Academy?
Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Композиция вместо наследования»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Go Academy?
Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Встраивание структур
- Встраивание интерфейсов
- Продвижение методов
- Композиция вместо наследования