Garantindo que estruturas incorporadas implementem a interface sem introduzir ambiguidade

Estou tentando limpar minha base de código, fazendo um melhor trabalho ao definir interfaces e usando estruturas incorporadas para reutilizar a funcionalidade. No meu caso, tenho muitos tipos de entidades que podem ser vinculados a vários objetos. Quero definir interfaces que capturem os requisitos e estruturas que implementam as interfaces que podem ser incorporadas às entidades.

// All entities implement this interface
type Entity interface {
  Identifier()
  Type()
}

// Interface for entities that can link Foos
type FooLinker interface {
  LinkFoo()
}

type FooLinkerEntity struct {
  Foo []*Foo
}

func (f *FooLinkerEntity) LinkFoo() {
  // Issue: Need to access Identifier() and Type() here
  // but FooLinkerEntity doesn't implement Entity
}

// Interface for entities that can link Bars
type BarLinker interface {
  LinkBar()
}

type BarLinkerEntity struct {
  Bar []*Bar
}

func (b *BarLinkerEntity) LinkBar() {
  // Issues: Need to access Identifier() and Type() here
  // but BarLinkerEntity doesn't implement Entity
}

Então, meu primeiro pensamento foi ter FooLinkerEntity e BarLinkerEntity apenas implementando a interface Entity.

// Implementation of Entity interface
type EntityModel struct {
    Id string
    Object string
}

func (e *EntityModel) Identifier() { return e.Id }
func (e *EntityModel) Type() { return e.Type }

type FooLinkerEntity struct {
  EntityModel
  Foo []*Foo
}

type BarLinkerEntity struct {
  EntityModel
  Bar []*Bar
}

No entanto, isso acaba com um erro de ambiguidade para todos os tipos que podem vincular Foos e Bars.

// Baz.Identifier() is ambiguous between EntityModel, FooLinkerEntity,
// and BarLinkerEntity.
type Baz struct {
    EntityModel
    FooLinkerEntity
    BarLinkerEntity
}

Qual é a maneira correta de estruturar esse tipo de código? Eu apenas faço uma asserção de tipo noLinkFoo() eLinkBar() chegar aIdentifier() eType()? Existe alguma maneira de obter essa verificação no tempo de compilação, em vez do tempo de execução?

questionAnswers(2)

yourAnswerToTheQuestion