Interface + Client struct + NewClient() - desing pattern

I am writing a package with some functionality. My standard approach is to create an interface I and a struct that implements it, and a New() function that takes in config values and returns a *struct that implements the interface. Note that pointer to my struct is actually implementing the interface.

Is this the standart Go approach ? When do you create an interface ?

I have gotten feedback that we can do without the interface, or that there is no benefit having the New function and simply instantiate that struct as needed. How legitimate is this ?

1 Like

Typically, your functions should receive interface-type parameters but return concrete-type values. Here are a few situations where I think that it makes sense to return interfaces instead of concrete types:

  • If the type you’re implementing is not exported (e.g. *myStruct vs. *Struct)

  • If the factory function returns a different implementation based on its parameters, e.g.:

    func CreateThing(options ThingOptions) Thing {
        if (options.DoThingA) {
            return &thingAImpl{}
        }
        return &thingBImpl{}
    }