嵌入相互依赖的结构/接口

I have 3 structures that are similar about 70%. So I'd like to extract some common part and create some extensions with specific methods and fields.

Final structure will work as follows:

  1. method .Start() from Common is called

  2. Start() calls method .Name() from specific part the latter return a string

  3. the returned result is being processed in (*Common).Process(), sometimes it should call specific's Format()

  4. But! Specific part have to call Common part's method, for example GetVerbosity()

Like this:

package common

type Common struct {
     Specificer 
}

func (c *Common) Start() {
     ...
     name := Specific.Name()
}

func (c *Common) GetVerbosity() {...}

type Specificer interface {
    Name() string
    Format() string
}

And specific part:

package specific1

// should implement common.Specificer interface
type Specific1 struct {
    // unexported fields
}

func (s *Specific1) Name() string {...}
func (s *Specific1) Format() string {
   // How to call it???
   Common.Method() 
}

This is similar to some frameworks - when another code calls your code, and also you call it's code.

How to implement this better? And how to create new structures? I tried:

  1. Embed Specific to Common, and embed vise versa:

    type Common struct {
        Specificer
    }
    
    type Specific1 struct {
       common.Common
       ...
    }
    
    // But this is little bit insane:
    func NewSpecific1() *common.Common {
        var s = Specific1{}
        return &common.Common{Specificer: &s}
    }
    
  2. Define 2 interfaces: Commoner and Specificer. And combined interface:

    package common
    type CommonSpecificer interface {
       Commoner
       Specificer
    }
    
    type Common struct {...}  // implements all the methods from Commoner
    
    func New() *Common {...}
    
    
    //////
    package specific1
    
    type Specific1 struct  { // implements all the methods from common.Specificer
       Common
       ...
    }  
    
    func NewSpecific1() *Specific1 {
      c := common.NewCommon(...)
      s := &Specific1{Common: c}
      return s
    }