종속성 반전 원리

Dependency Inversion Principle은 엔티티가 구체화가 아닌 추상화에 의존해야 한다고 명시합니다. 고수준 모듈은 저수준 모듈에 의존해서는 안 됩니다. 둘 다 추상화에 의존해야 합니다.

High-level modules should not depend on low-level modules. Both should depend on abstraction.



고수준 모듈에 대해 이야기할 때 도구 또는 라이브러리를 구현하는 작업을 실행하는 클래스를 말하고, 저수준 모듈에 대해 이야기할 때 작업을 실행하는 데 필요한 도구 또는 라이브러리를 말합니다.

원리는 분리, 분리 또는 분리를 의미하는 분리를 허용합니다. 이것은 의존성을 줄이고 미래에 다른 도구를 더 쉽게 구현할 수 있게 함으로써 우리에게 도움이 됩니다.

예시



Candy Store가 있고 결제 프로세스를 개발 중이라고 가정해 보겠습니다. 처음에는 결제 프로세서로 Stripe만 구현할 계획이었습니다. Stripe은 거래를 하기 위해 금액이 센트로 전달되어야 합니다. 우리의 수업은 다음과 같이 보일 것입니다:

//Checkout.js
class Checkout {
  constructor() {
    this.paymentProcessor = new Stripe('USD');
  }

  makePayment(amount) {
    //Multiplying by 100 to get the cents
    this.paymentProcessor.createTransaction(amount * 100);
  }
}

//Stripe.js
//Custom Stripe implementation that calls the Stripe API
class Stripe {
  constructor(currency) {
    this.currency = currency;
  }

  createTransaction(amount) {
    /*Call the Stripe API methods*/
    console.log(`Payment made for $${amount / 100}`);
  }
}


종속성 반전 원칙을 위반하여 Checkout 클래스(상위 모듈)와 Stripe(하위 수준 모듈) 사이에 종속성을 생성했음을 주목하세요. 종속성은 금액을 센트로 변환할 때 특히 두드러집니다. Checkout는 어떤 지불 프로세서가 사용되는지 신경 쓰지 않아야 하며, 거래를 만드는 데만 관심이 있습니다.

이 두 모듈을 분리하려면 결제 프로세서와 결제 프로세서 사이에 중개자를 구현하여 어떤 결제 프로세서를 사용하든 Checkout 클래스가 항상 동일한 메서드 호출로 작동하도록 추상화를 생성해야 합니다. 새로운PaymentProcessor 클래스는 사용할 결제 프로세서(이 경우 Stripe)에 모든 것을 적용하는 역할을 합니다. 중간 클래스에는 다음 코드가 있습니다.

//PaymentProcessor.js
class PaymentProcessor {
  constructor(processor, currency) {
    this.processor = processor;
    this.currency = currency;
  }

  createPaymentIntent(amount) {
    const amountInCents = amount * 100;
    this.processor.createTransaction(amountInCents);
  }
}


보시다시피 createPaymentIntent 클래스의 PaymentProcessor는 금액을 센트로 변환하고 있습니다. 이제 추상화를 구현하기 위해 Checkout 클래스를 리팩토링합니다.

//Checkout.js
class Checkout {
  constructor(paymentProcessor) {
    this.paymentProcessor = paymentProcessor;
  }

  makePayment(amount) {
    this.paymentProcessor.createPaymentIntent(amount);
  }
}


이제 지불 프로세서를 변경해야 하는 경우 Stripe 대신 새 프로세서를 PaymentProcessor 생성자에 전달하여 변경할 수 있습니다. 그런 다음 PaymentProcessorCheckout에 전달합니다.

//index.js
const paymentProcessor = new PaymentProcessor(new Stripe('USD'), 'USD');
const checkout = new Checkout(paymentProcessor);


이제 Stripe를 센트로 변환할 필요가 없지만 모든 거래에서 사용할 통화를 요구하는 다른 지불 프로세서로 교체하라는 요청을 받았다고 상상해 보십시오. 결과 코드는 다음과 같습니다.

//Checkout.js
class Checkout {
  constructor(paymentProcessor) {
    this.paymentProcessor = paymentProcessor;
  }

  makePayment(amount) {
    this.paymentProcessor.createPaymentIntent(amount);
  }
}

//PaymentProcessor.js
class PaymentProcessor {
  constructor(processor, currency) {
    this.processor = processor;
    this.currency = currency;
  }

  createPaymentIntent(amount) {
    this.processor.createTransaction(amount, this.currency);
  }
}

//BetterProcessor.js
class BetterProcessor {
  createTransaction(amount, currency) {
    console.log(`Payment made for ${amount} ${currency}`);
  }
}

//index.js
const paymentProcessor = new PaymentProcessor(new BetterProcessor(), 'USD');
const checkout = new Checkout(paymentProcessor);

PaymentProcessor 클래스에 전달된 프로세서만 변경하고 Checkout 클래스는 그대로 유지되는 방법에 주목하십시오. 중간 클래스PaymentProcessor를 프로세서 요구 사항에 맞게 조정했습니다.

종속성 반전 원칙에 따라 Checkout와 중간 클래스PaymentProcessor를 구현하여 사용하는 프로세서 간의 종속성을 제거했습니다.

좋은 웹페이지 즐겨찾기