简体   繁体   中英

Multiple implementation of the same method that might have differents dependencies with Go and Interfaces

I have a problem about using interfaces.

I have a Compute(a, b int) Method that has 2 implementations, depending on the receiver.

func (addition *Addition) Compute(a, b int) int{
    return a+b
}

func (mult *Multiplication) Compute(a, b int) int{
    return a*b
}


type myInterface{
    Compute(a, b int) int
}

Let's imagine I need to call a webService in Multiplication to get the value of a.

Now we have:

func (mult *Multiplication) Compute(iface WSInterface, a, b int) int{
    a := iface.getA()
    return a*b
}

Now, I will need to add iface WSInterface into Compute() Interface definition, and add it to Addition, even if it doesn't need it.

I will end with:

type Addition struct{}

type Multiplication struct{}


func main() {
    addition := &Addition{}
    multiplication := &Multiplication{}
    res1 := addition.Compute(nil, 1, 2)
    res2 := addition.Compute(multiplication, 3, 4)
    fmt.Print(res1, res2)
}

type WSInterface interface {
    getA() int
}

func (mult *Multiplication) getA() int {
    return 1 // Mocked
}

type myInterface interface {
    Compute(iface myInterface, a, b int) int
}

func (addition *Addition) Compute(iface WSInterface, a, b int) int {
    return a + b
}

func (mult *Multiplication) Compute(iface WSInterface, a, b int) int {
    return iface.getA() * b
}

but in Addition, it will not be used.

In real life, you can have several dependencies to different microservices, and I find it not so elegant to define params that you will not use in your function. There must be something wrong here.

Is it ok to do this, is it a bad pattern, or how should I do to fix it?

These special interfaces/objects should be passed in the constructor, keeping the interfaces themselves clean.

Something like:

type Multiplication struct {
  iface otherInferface
  // .. other Multiplication-specific fields
}

func NewMultiplication(iface otherInterface) *Multiplication {
  return &Multiplication{iface: iface}
}

And then:

func (mult *Multiplication) Compute(a, b int) int{
    a := mult.iface.getA()
    return a*b
}

So your myInterface remains simple and clean:

type myInterface interface {
  Compute(a, b int)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM