Search code examples
gointerfacecoding-style

How do I refactor this code with Interfaces, and if so, should I?


I'm programming a piece of software that consumes APIs from different services and the methods would be the same but different execution. I wonder if the code can be organized in interfaces or I just keep working like this:

type endPoint struct{
    serverName string
}

func (this *endPoint) getLastDateURL () string{
    if this.Name ="A"{
        return "api.someAWebsite.com/getLastDate"
    }
    if this.Name ="B"{
        return "api.someBWebsite.com/getLastDate"
    }
    return ""
}

func (this *endPoint) processData () output{
    if this.Name ="A"{
        //process in some way
        return
    }
    if this.Name ="B"{
                //process in some different way
                return
    }
    return
}

The interface alternative I'm thinking is about this:

struct endPoint interface{
    getLastDateURL()
    processData()
}

...
Do each method for each API provider
How would I use it then?

My end goal is to have maintainable and clean code. Honestly hate the fact that I'd have to write the same methods for each end point to implement the interface, but perhaps I do not have the Interface concept just so clear yet or there is little advantage in using interfaces in this case with again, the end goal of maintainable and clean code.

Thanks.


Solution

  • // "struct endPoint interface" is invalid, and signatures are missing their return types:
    type endPoint interface{
        getLastDateURL() string
        processData() output
    }
    

    How would I use it then?

    I can't give a complete solution since you haven't shown how you're using your current code, but in general you'd have:

    • Something that instantiates an implementation - whatever would be setting Name in the current implementation would instead create an instance of a concrete type implementing endPoint
    • Something that calls getLastDateURL and/or processData - instead of receiving an *endPoint struct, it would receive an endPoint interface value, and then wouldn't care what the underlying implementation is; it would just call the methods, pretty much just like it does today

    My end goal is to have maintainable and clean code.

    This is probably a good way to achieve that, but it depends on context not shown in the question.

    Honestly hate the fact that I'd have to write the same methods for each end point to implement the interface

    You're already writing an implementation for each end point, you're just writing them all in the same methods. The amount of code you have to write is almost identical, but the resulting code is cleaner & more organized - for example, each concrete implementation could be in its own file, rather than having to be all in the same methods. With many/complex providers, your current solution becomes increasingly difficult to navigate if you ever need to change it or add a provider.