title: Wrapping multiple implementations in Go
body: <p>I have an application that has multiple concurrent implementations of the same API (e.g. one backed by a SQL database and another by a dataset stored in an XML file). What I'd really like to do is to define a parent type for each type of thing in the API that</p>
  
  <ol>
  <li><p>holds the member variables that are common to all of the implementations and</p></li>
  <li><p>defines the methods that all implementations must have.</p></li>
  </ol>
  
  <p>So, in (invalid) Go, I want to do something like:</p>
  
  <pre><code>type Person interface {
      Name string
      Title string
      Position string
      Boss() *Person
  }
  
  type Person_XML struct {
      Person
  }
  
  func (p *Person_XML) Boss() (*Person, error) {
      // Poke around an XML document and answer the question
      return boss, nil
  }
  
  type Person_SQL {
      Person
  }
  
  func (p *Person_SQL) Boss() (*Person, error) {
      // Do a DB query and construct the record for the boss
      return boss, nil
  }
  </code></pre>
  
  <p>But, of course, that's not legal since only structs have member variables and only interfaces have member functions. I could do this with just interfaces like this:</p>
  
  <pre><code>type Person interface {
      Name() string
      Title() string
      Position() string
      Boss() Person
  }
  
  type Person_XML struct {
      NameValue string
      TitleValue string
      PositionValue string
      Person
  }
  
  func (p *Person_XML) Name() string {
      return p.NameValue
  }
  
  func (p *Person_XML) Title() string {
      return p.TitleValue
  }
  
  func (p *Person_XML) Position() string {
      return p.PositionValue
  }
  
  func (p *Person_XML) Boss() (Person, error) {
      // Poke around an XML document and answer the question
      return boss, nil
  }
  </code></pre>
  
  <p>and similarly for other implementations. Is there an alternative that doesn't force me to turn member variables into member functions? What's best practice for such a use case?</p>