구조체 초기화 시점에 의존성이 주입되는 경우
특정 메서드가 외부패키지인 billingService에 의존적인 구조
- Bill 구조체는 선언 시점에 billingService를 주입받아야 하기 때문에, billingService에 의존적인 구조를 갖게됨
type Bill struct {
price int
productName string
billingService billing.Service
}
func NewBill(price, productName string, billingService billing.Service) Bill {
return Bill {
price: price,
productName: productName,
billingService: billingService
}
}
func (b Bill) Billing() (err error) {
return b.billingService.Billing(b.price, b.productName)
}
구조체가 초기화 된 후에도 필요에 따라 각기 다른 구현의 의존성을 주입받을 수 있는 구조
- private interface를 활용해 외부패키지와 상관 없이 동작하도록 함. billingService는 외부에서 주입할 수 있다.
type Bill struct {
price int
productName string
}
func NewBill(price, productName string) Bill {
return Bill {
price: price,
productName: productName
}
}
type billerFromOutside interface {
Billing(price int, productName string) error
}
func (b Bill) Billing(biller billerFromOutside) (err error) {
return biller.Billing(b.price, b.productName)
}
아래의 구조에 따르면 Bill 구조체를 만들때는 billingService와 전혀 상관이 없다.
billerFromOutside를 구현하고있는 구조체만 Billing 메서드의 인자로 넣어주면 된다.
이렇게 하면 Bill 구조체를 만드는 시점이 아닌, Billing 메서드를 호출하는 시점에 외부에서 의존성을 주입해줄 수 있다.
type IamportBiller struct {
accessToken string
secretToken string
}
func NewIamportBiller(accessToken, secretToken string) IamportBiller {
return IamportBiller {
accessToken: accessToken,
secretToken: secretToken,
}
}
func (b IamportBiller) Billing(price int, productName string) (err error) {
// iamport에 결제하는 로직....
return err
}
type NicepayBiller struct {
accessToken string
secretToken string
}
func NewNicepayBiller(accessToken, secretToken string) NicepayBiller {
return NicepayBiller {
accessToken: accessToken,
secretToken: secretToken,
}
}
func (b NicepayBiller) Billing(price int, productName string) (err error) {
// nicepay 결제하는 로직
return err
}
func main() {
// iamport Biller
iBiller := NewIamportbiller("abc", "xyz")
// nicepay Biller
nBiller := NewNicepayBiller("abc", "xyz")
price := 500
productName := "휴지"
productBill := Bill{price, productName}
// bill with iamport
productBill.Billing(iBiller)
// bill with nicepay
productBill.Billing(nBiller)
}