22/12/2020 - GO
İki tane veritabanı repository sınıfına bağlı olan bir servisinizin olduğunu varsayın. Bu durumda her ikisini de servis yapısında saklarsınız. Bu, az miktarda bağımlılık için uygundur, ancak daha fazla dependency injection yapısı varsa, çalışabileceğiniz büyük bir yapıya ve dağınık bir koda sahip olursunuz. Aynı şeyi farklı repository sınıfları için yapan başka servislere de sahip olabilirsiniz. Sonunda her yerde bir sürü kopya kod oluşabilir. Bu sorunun çözümü basittir. Tüm alt repository sınıf arayüzlerini içinde saklayacak bir ana yapı oluşturacağız. İhtiyaç duyduğumuz yerde sadece ana depoyu kullanacağız. Bu, tüm gömülü repository sınıflarına ondan erişmemizi sağlayacaktır. Biraz strateji modeli gibi.
├── cmd
│ └── client
│ └── main.go
└── internal
├── dao
│ ├── article.go
│ └── label.go
├── repository
│ ├── article.go
│ ├── label.go
│ └── repository.go
└── service
├── article.go
└── label.go
package dao
import "time"
type ArticleRepository interface {
Insert(article *Article) error
Find(ID string) (*Article, error)
}
type Article struct {
ID string
Title string
PublishedAt time.Time
}
package dao
type LabelRepository interface {
Insert(label *Label) error
List(limit uint8) ([]*Label, error)
}
type Label struct {
ID string
Name string
}
package repository
import "github.com/you/client/internal/dao"
type Repository struct {
Article dao.ArticleRepository
Label dao.LabelRepository
}
func New() Repository {
return Repository{
Article: article{},
Label: label{},
}
}
package repository
import (
"log"
"github.com/you/client/internal/dao"
)
type article struct{}
func (a article) Insert(article *dao.Article) error {
log.Println("inserting article")
return nil
}
func (a article) Find(ID string) (*dao.Article, error) {
log.Println("finding article")
return nil, nil
}
package repository
import (
"log"
"github.com/you/client/internal/dao"
)
type label struct{}
func (l label) Insert(label *dao.Label) error {
log.Println("inserting label")
return nil
}
func (l label) List(limit uint8) ([]*dao.Label, error) {
log.Println("listing labels")
return nil, nil
}
package service
import (
"github.com/you/client/internal/dao"
"github.com/you/client/internal/repository"
)
type Article struct {
repo repository.Repository
}
func NewArticle(repo repository.Repository) Article {
return Article{repo: repo}
}
func (a Article) DoSomething() {
_ = a.repo.Article.Insert(&dao.Article{})
_, _ = a.repo.Article.Find("id")
}
package service
import (
"github.com/you/client/internal/dao"
"github.com/you/client/internal/repository"
)
type Label struct {
repo repository.Repository
}
func NewLabel(repo repository.Repository) Label {
return Label{repo: repo}
}
func (l Label) DoSomething() {
_ = l.repo.Label.Insert(&dao.Label{})
_, _ = l.repo.Label.List(1)
}
package main
import (
"github.com/you/client/internal/repository"
"github.com/you/client/internal/service"
)
func main() {
repo := repository.New()
articleService := service.NewArticle(repo)
articleService.DoSomething()
labelService := service.NewLabel(repo)
labelService.DoSomething()
}
$ go run -race cmd/client/main.go
2020/12/22 23:26:14 inserting article
2020/12/22 23:26:14 finding article
2020/12/22 23:26:14 inserting label
2020/12/22 23:26:14 listing labels