해결됨
제미니의 개발실무 - 지속 성장 가능한 소프트웨어를 만들어가는 방법모듈에 대한 단방향 의존
안녕하세요. 제미니님 이번에도 좋은 강의를 제공해주셔서 감사합니다.모듈 분리에서 궁금한 내용이 있는데요. 제미니님이 제공해주신 PaymentAPI 와 DB 모듈을 별도로 했다고 했을 때 API 규격에 맞게 DB 모듈이 구현이 되어야 한다고 생각하고 있습니다. 즉, 해당 PaymentAPI 에서 제공하는 DB 접근에 대한 인터페이스를 DB 모듈이 구현하는 의존성 역전 원칙을 적용한 상황입니다.하지만, 이 상황에서 단방향 모듈 참조를 하게 된다면 DB 모듈은 PaymentAPI 가 제공하는 인터페이스의 유무를 알 수가 없게 되는데요. 저는 위 문제에 대한 해결방법으로 두 가지가 떠오릅니다.모듈 분리 시 API 모듈에 인터페이스를 만들고 DB 모듈 교체에 따른 새로운 구현체를 구현한다.(모듈 교체에 따라 이전 모듈에 대한 클래스 참조가 사라져 컴파일에러가 발생하게 되고 주석처리가 필요하다) 모듈 교체 시 이전 모듈에서 사용했던 인터페이스를 하위 모듈에서 똑같이 생성해주고 동일한 인터페이스를 참조하도록 하여 상위 모듈에는 변화를 주지 않는다. (변화가 최소화되지만 인터페이스가 많을 수록 구현도가 올라간다. 인터페이스를 동일하게 만들거라는 보장이 되어야 한다.)1번 코드paymentAPI {
// implementation 'project:paymentDB'
// implementation 'project:paymentDB2'
interface CommandPort {
fun save(command: PaymentCommand)
}
class PaymentDBImplV1 : CommandPort {
override fun save(command: PaymentCommand) {
paymentDB.saveV1(command); // paymentDB2 모듈 사용 시 주석 처리
}
}
class PaymentDBImplV2 : CommandPort {
override fun save(command: PaymentCommand) {
paymentDB2.saveV2(command); // paymentDB1 모듈 사용 시 주석 처리
}
}
}
paymentDB {
implementation 'A.DB'
}
paymentDB2 {
implementation 'B.DB'
}2번 코드paymentAPI {
// implementation 'project:paymentDB'
// implementation 'project:paymentDB2'
class PaymentAPILogic(val paymentDB: CommandPort){
fun save(command: PaymentCommand) {
paymentDB.save(command); // paymentDB2 모듈 사용 시 주석 처리
}
}
}
paymentDB {
implementation 'A.DB'
interface CommandPort {
fun save(command: PaymentCommand)
}
class PaymentCommandImpl : CommandPort {
override fun save(command: PaymentCommand) {
DB.save(command);
}
}
}
paymentDB2 {
implementation 'B.DB'
interface CommandPort {
fun save(command: PaymentCommand)
}
class PaymentCommandImpl : CommandPort {
override fun save(command: PaymentCommand) {
DB.save(command);
}
}
}간단하게 코드를 작성하면 위와 같은 형태가 될 것 같습니다.제미니님은 어떠한 방향으로 설계를 하시는지 혹은 제 질문에서 제가 잘 못 이해한 부분이 있어 이러한 방법으로 사고가 흘러가는지 말씀을 들어보고 싶습니다.마지막으로 유튜브 및 인프런에서 귀한 지식과 귀한 시간을 제공해주셔서 항상 감사합니다!