У меня есть общий обработчик, который содержит данные, необходимые для выполнения всего, что он должен делать.
type Handler struct {
info HandlerInfo
}
Затем структура отправителя, которая в равной степени имеет свою собственную информацию.
type Sender struct {
info SenderInfo
}
Наконец, есть получатель, который также имеет свою собственную информацию.
type Receiver struct {
info ReceiverInfo
}
Обработчик генерирует связывающие пары при выполнении программы.Я не хочу приводить примеры типов связи между различными структурами, которые я определил, так как я хочу, чтобы мой пример был максимально широким.
func (h Handler) Do() {
for /* something happens */ {
sender := Sender{}
receiver := Receiver{}
}
sender.DoSomething()
if sender.ShouldSend() {
receiver.Receive()
}
}
Здесь все выглядит довольно просто, но ясталкиваются с двумя проблемами:
1) Как обрабатывать данные, передаваемые Отправителем и Получателем без избыточности?
2) Как обрабатывать данные, используемые Обработчиком, но этоОтправитель и Получатель также должны использовать?
1) Как обрабатывать данные, передаваемые Отправителю и Получателю без избыточности?
Кто-то может сказать, что необходимо только заполнить обе структуры поэтапно тем, что им нужно
Но это делает вещи слишком избыточными IMO:
func DoSomethingAndFill() {
data1 := generateSomeData1()
recv.Receive1(data1)
sender.Send1(data1)
data2 := generateSomeData2()
recv.Receive2(data2)
sender.Send2(data2)
}
Я сказал себе, что могу (буквально) разделить базовую структуру, содержащую данные, которые должны быть переданы:
type MetaData struct {
Data1 Data
Data2 Data
}
type Sender struct {
*MetaData
info SenderInfo
}
type Receiver struct {
*MetaData
info ReceiverInfo
}
А при инициализации мне нужно было только поставить тот же указатель?
func init() {
md := MetaData{}
recv, send := Receiver{&md}, Sender{&md}
}
Но это заставляет меня делать две вещи:
С одной стороны, если я хочу очистить вещи и сделать пакет для Получателя, а другой - для Отправителя, я должен сделать всеполя экспортируемых MetaData, которые, хотя и не сильно плохи, не идеальны.
С другой стороны, я вынужден сделать код немного более запутанным, так как при заполненииСтруктура Мне приходится перетаскивать то, что входит в Sender, Receiver и MetaData.
2) Как обрабатывать данные, используемые Handler, но которые Sender и Receiver также должны использовать?
Первое, что мне пришло в голову, это сделать что-то вроде обратной ссылки на родительскую структуру:
type Handler struct {
Info HandlerInfo
}
type Sender struct {
handler Handler
info SenderInfo
}
type Receiver struct {
handler Handler
info ReceiverInfo
}
func (h Handler) MakeRecvAndSend() {
recv, send := Receiver{
handler: h,
}, Sender{
handler: h,
}
}
И на первый взгляд это кажется довольно хорошим, но опять же, если Senderи Receiver находятся в разных пакетах, и поскольку круговой импорт в Golang не разрешен, это невозможно.
Другое решение, о котором я подумал, - копировать соответствующую информацию по частям:
type Handler struct {
info1 HandlerInfo
info2 HandlerInfo
}
type Sender struct {
handlerInfo HandlerInfo
info SenderInfo
}
type Receiver struct {
handlerInfo HanlderInfo
info ReceiverInfo
}
func (h Handler) MakeRecvAndSend() {
recv, send := Receiver{
handlerInfo: h.info1,
}, Sender{
handler: h.info2,
}
}
Но это очень многословно, и, в зависимости от способа генерации отправителей и получателей, я боюсь, что это повлияет на скорость / память во время выполнения.
Если вы уже столкнулись с такими проблемами, я бынравится ваш отзыв и то, как вы решили это.Я также интересуюсь любой теоретической мыслью, которой вы могли бы поделиться!
Thx!