modern-go-application: Some violations of CodeReviewComments

  1. Repeatation
    • Package helloworld contains a function NewHelloWorld.
    • So the client would initialize the HelloWorld type as helloworld.NewHelloWorld which is simply repeatation of the fact that helloworld package contains a HelloWorld and is not recommended Package Names
    • This should instead be helloworld.New()
  2. Interfaces
    • Package helloworld contains an interface HelloWorld and function NewHelloWorld returns this interface type instead of concrete type. Interfaces on implementor side as an abstraction has no meaning
    • Package helloworld should contain a concrete type HelloWorld which is returned by helloworld.New function as recommended here
    • Clients who need to use features of HelloWorld type can define interfaces with only the features they really need and inject instance of HelloWorld as an implementation.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 17 (10 by maintainers)

Most upvoted comments

Good idea, created an issue #20 for that

@sagikazarmark thanks for considering the suggestions.

I have been planning to setup a sample project myself. My idea was to build a full blown application ( droplets ) which could be used as a reference project by gophers. But wasn’t able to actively work on it due to time constraints. So kudos for your effort.

Here is an experimental PR, but I’m gonna stare at it for a while to decide whether I like it, before I merge it: #19 🙂

Here is round two: #18

Okay, first round is here: #17

Let’s say helloworld package had 2 clients A and B. Client B requested for a feature called SayReverse in addition to already existing SayHello feature. You added this to helloWorld struct. But since this struct is unexported, client B will still not be able to use the added feature. How do you solve this ? If you thought you could add SayReverse signature to HelloWorld interface, you would be violating Interface Segregation Principle, also possibly breaking client A. (because, even though, client A doesn’t need the new feature it’s going to be forced since it’s importing your interface instead of defining an interface matching it’s requirements)

This is where Go’s structural typed interfaces shine because, client can define interfaces anytime it wants without really breaking anything since implementations are truly independent of any interface name. (i.e., no implements X in implementation)

That’s why the recommendation Accept interfaces, return structs