Go에서 의존성 더 쉽게 주입하는법

Sean Kim·2023년 4월 6일
0

GoLang

목록 보기
4/5

의존성 주입을 위한 private interface 활용

구조체 초기화 시점에 의존성이 주입되는 경우

  • 특정 메서드가 외부패키지인 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)
  }
profile
이것저것 해보고있습니다.

0개의 댓글