Dependency Inversion Principle
Information
Dependency inversion principle(DIP) states that high-level modules should not depend on low-level modules. Both should depend on abstractions.
The idea is to reduce the coupling between modules, it leads to code being easier to change.
DIP is a way to achieve Open Closed Principle
Example
If we have service that needs repository to work we can inject any implementation of it:
real repository, like mongo or postgres
mock repository for testing
logging repository for debugging without using real database
file repository for some static data
...
In this example we have service that needs repository to work. We can inject any implementation during assembling of components
// abstract module
type Repository interface {
...
}
// service implementation
type Service struct {
repository Repository
}
func NewService(repository Repository) *Service {
return &Service{repository: repository}
}
func (s *Service) DoSomething(...) {
s.repository.DoSomethingElse(...)
}
func buildService(cfg Config) Service{
var repository Repository
swich cfg.RepositoryType {
case "mongo":
repository := mongo.NewRepository(cfg.MongoStuff)
case "postgres":
repository := postgres.NewRepository(cfg.PostgresStuff)
case "logging":
repository := logging.NewRepository()
}
return serviceimplementation.NewService(repository)
}
Resources
#principle