Помните, что Go не имеет объектно-ориентированного наследования так же, как Java. Похоже, вы пытаетесь написать абстрактный базовый класс, который инкапсулирует все части «сообщения»; это не совсем типичный стиль Go.
Поля, которые вы описываете, являются типичными метаданными сообщения. Вы можете инкапсулировать эти метаданные в структуру чисто данных. Это не обязательно требует какого-либо поведения и не обязательно требует методов получения и установки.
type MessageMeta struct {
Source Agent
Destination Agent
}
Более объектно-ориентированный подход заключается в том, что сообщение имеет (изменяемый) блок метаданных и (неизменяемый, кодированный) полезную нагрузку.
import "encoding"
type Message interface {
encoding.BinaryMarshaler // requires MarshalBinary()
Meta() *MessageMeta
}
type SomeMessage struct {
MessageMeta
Greeting string
}
func (m *SomeMessage) Meta() *MessageMeta {
return &m.MessageMeta
}
func (m *SomeMessage) MarshalBinary() ([]byte, error) {
return []byte(m.Greeting), nil
}
Более процедурный подход, при котором эти две вещи рассматриваются отдельно, также является разумным. В этом случае нет интерфейса для того, что является «сообщением», вы просто передаете кодированную полезную нагрузку; интерфейсы стандартной библиотеки, такие как encoding.BinaryMarshaler
, могут иметь здесь смысл. Вы можете включить это в интерфейс более низкого уровня, который является частью вашей библиотеки.
func Deliver(meta *MessageMeta, payload []byte) error { ... }
Переводить один на другой легко
func DeliverMessage(m Message) error {
payload, err := m.Payload()
if err != nil {
return err
}
meta := m.Meta()
return Deliver(meta, payload)
}
Если одно из полей метаданных «доставлено», то при передаче указателя на объект метаданных по всей цепочке можно обновить это поле в исходном объекте.
Я бы не стал беспокоиться о сборке мусора как о первоклассном подходе, за исключением того, чтобы не быть чрезмерно расточительным и проверять распределение объектов, если GC начинает появляться в профилях. Создание двух объектов вместо одного, вероятно, не будет большой проблемой здесь.