🙈
クリーンアーキテクチャをGoでする場合にInterfaceを無くす
クリーンアーキテクチャを知っている人向けです。
上辺しか喋らないので話半分です。
途中でクリーンアーキテクチャではなくなります。
Interfaceをなくそうと思ったきっかけ
とある方からGoで無駄なInterfaceは良くないと言われたことがきっかけです。
使いまわせないInterfaceはあまり良くないらしい?です。
UseCase層を無くす
goではこんな風に実装しますが複雑さをなくすためにレイヤーを一つ削除しようという魂胆です。
今回は省いていますが実際はこの実装例にInterfaceが実装されています。
type Entity struct {
...
}
type Repository struct {
...
}
func (r *Repository) Insert(entity *Entity) {
...
}
type Usecase struct {
Repository *Repository
}
func (u *Usecase) Post(entity *Entity) {
r.Repository.Insert(entity)
}
type Controller struct {
Usecase *Usecase
}
func (c *Controller) Post(ctx) {
entity = ctx.Hoge()
c.Usecase.Post(entity)
}
func main() {
repo := Repository{}
use := UseCase {Repository: repo}
ctrl := Controller {Usecase: use}
ctrl.Post(ctx)
}
実装例
単純にUsecase構造体を削除してControllerにRepositoryを持たせます。
type Entity struct {
...
}
type Repository struct {
...
}
func (r *Repository) Insert(entity *Entity) {
...
}
type Controller struct {
Repository *Repository
}
func (c *Controller) Post(ctx) {
entity = ctx.Hoge()
c.Repository.Insert(entity)
}
func main() {
repo := Repository{}
ctrl := Controller {Repository: repo}
ctrl.Post(ctx)
}
Interfaceを無くす
Interfaceをただ削除するとmockが作れなくなりテストが行いにくくなります。
のでまずController層とEntity層を切り離します。
ControllerにEntityの実態を持たせないようにします。
この時点でもうCleanアーキテクチャではないですが……。
実装例
実態を持たせないようにしていきます。
この時点でInterfaceを削除できます。
type Entity struct {
...
}
type Repository struct {
...
}
func (r *Repository) Insert(entity *Entity) {
...
}
type Controller struct {}
func (c *Controller) Post(ctx) {
entity = ctx.Hoge()
c.Repository.Insert(entity)
}
func main() {
repo := Repository{}
ctrl := Controller {Repository: repo}
ctrl.Post(ctx)
}
そして関数の引数をInterfaceが変わりにしてControllerにRepositoryの関数を渡せるようにします。
type Entity struct {
...
}
type Repository struct {
...
}
func (r *Repository) Insert(entity *Entity) {
...
}
type Controller struct {}
func (c *Controller) Post(ctx, insert func(*Entity)) {
entity := ctx.Hoge()
insert(entity)
}
func main() {
repo := Repository{}
ctrl := Controller {Repository: repo}
ctrl.Post(ctx, repo.Insert)
}
これでInterfaceを無くせました。
問題点
必要な関数が増えると引数も増える
意図してない関数が渡される可能性がある
Discussion