Hacker News new | past | comments | ask | show | jobs | submit login

Sorry, forgot about mentioning the very language the OP was about. That was stupid.

You would use the "New" constructor function pattern in this case, using a higher order function called at injection time to keep it reusable and hide everything. I also prefer keeping the struct it returns as unexported so you get full encapsulation, but golint doesn't like it. I guess this is a personal issue.




> You would use the "New" constructor function pattern in this case, using a higher order function called at injection time to keep it reusable and hide everything.

Spot on. I love the decorator pattern for dependency injection.

    type Server struct {
    	logger *logrus.Logger // optional
    	store databaste.Store // required
    }
    
    type ServerOption func(Server) Server
    
    func WithLogger(logger *logrus.Logger) ServerOption {
    	return func(s Server) Server {
    		s.logger = logger
    		return s
    	}
    }
    
    func NewServer(store database.Store, options ...ServerOption) *Server {
    	s := Server{store: store}
    	for _, option := range options {
    		s = option(s)
    	}
    	return &s
    }
    
    func main() {
    	myServer := NewServer(myStore, WithLogger(myLogger))
    }




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: