Search code examples
godesign-patterns

What is best pattern to reuse Go interface without tripping cyclic dependencies


I have this simple package declaration where package "a" defines an interface "A" but I need to use the interface in package "b" for type inference and then the implementation of b.Request() in DoRequest() of "a" this means having to import the package in a cyclic way.

My question is if there is a none complicated approach to this design to avoid compiler cyclic dependency error ?.

NOTE to avoid putting "a" and "b" in the same package

package b

import "a"

func Request(t a.A){
m := t.GetMethod()
payload := t.GetPayload()
}

And Package "a" declaration

package a

import "b"


type A interface {
 GetMethod () string
 GetPayload () string
}

type ImplementA struct {
}

func (imp ImplementA)GetMethod() string{
return ""
}

func (imp  ImplementA) GetPayload() string{
return ""
}

func (imp ImplementA) DoRequest(){
  b.Request(imp)
}

Solution

  • It is considered best practice in go to define interfaces where they are used. So in package b, define an interface with those methods required by the function in package b.

    You can still add other functions in package a. The interface from package b can be embedded if you also need to define an interface in package a.

    For example:

    package b
    
    type AInterface interface {
      GetMethod () string
      GetPayload () string
    }
    
    func Request(t AInterface) {
      m := t.GetMethod()
      payload := t.GetPayload()
    }
    

    Then package A would just contain the implementation.

    package a
    
    import "b"
    
    type ImplementA struct {
    }
    
    func (imp ImplementA) GetMethod() string {
      return ""
    }
    
    func (imp ImplementA) GetPayload() string {
      return ""
    }
    
    func (imp ImplementA) DoRequest() {
      b.Request(imp)
    }