코드 재사용 남용: 마이크로 서비스에 대한 생각

부인 성명



이 게시물은 마이크로 서비스로 개발할 때 잘못될 수 있는 사례를 구축하려고 시도한 개인적인 생각에 더 가깝습니다. 제 목적은 단순히 제 생각을 공유하는 것이 아니라 제 학습 과정의 일부로 여기에서 언급할 내용과 다를 수 있는 다른 의견을 환영하는 것입니다. 먼저, 제 글을 읽어주시고 댓글(있는 경우)을 남겨주셔서 대단히 감사합니다 🙂

소개



우리가 대학에서 배운 것의 일부로 또는 소프트웨어 개발에 대해 배우기 시작한 사람들을 위해 우리는 코드를 재사용하도록 배웠고 이것이 우리가 함수를 만드는 이유 중 하나입니다. 뿐만 아니라 "바퀴를 다시 발명하지 마십시오"또는 DRY 원칙과 같은 용어는 우리에게 그것을 말해줍니다. 그러나 문제는 그것들이 절대적인 것입니까? 나는 모든 것이 맥락 속에 있어야 한다고 믿는다.

문제



다음은 "나에게"재사용이 적용되지 않아야 하는 예 중 하나입니다.

아래 다이어그램에 설명된 대로 서비스 A가 서비스 B를 호출하고 서비스 B가 서비스 C를 호출하는 다음과 같은 상황이 있다고 가정합니다.



C의 응답 모델, 열거형, 개체 또는 DTO가 B에 "재사용"된 다음 A에 전달되면 문제가 발생합니다. 아래 스니펫을 참조하십시오.

interface ResponseC {
    prop1: string
    prop2: string
}

const endpointC: Promise<ResponseC> = async() => {
  ...

  return { prop1, prop2 }
}



import { ResponseC } from 'path-to-c-or-common'

const endpointB: Promise<ResponseC> = async () => {
  ...
  const { prop1, prop2 } = await serviceC.endpointC()

  return { prop1, prop2 }
}




import { ResponseC } from 'path-to-c-or-common'

const endpointA: Promise<Omit<ResponseC, "prop2">> = () => {
  ...
  const { prop1, prop2 } = await serviceB.endpointB()

  return { prop1 }
}


그래서 문제가 무엇입니까?

위의 재사용 사용 사례는 마이크로 서비스 아이디어 자체의 목적 또는 반 패턴을 무효화합니다.

마이크로 서비스의 기본 아이디어 중 하나는 책임 분리/느슨하게 결합하는 것입니다(https://microservices.io 페이지에서 직접 읽을 수 있음).

인수 #1



다른 서비스를 호출하기 위해 매번 매핑을 수행해야 하기 때문에 각 마이크로가 고유한 유형을 가지면 개발 속도가 느려진다고 주장할 수 있습니다.

그러나 그 "추가"작업을 갖는 것은 우리 시스템을 "분리"하게 만들고 미래에 더 많은 유연성을 제공할 것입니다.

서비스 C에서 공유 모델의 형태를 변경하기 위해 변경이 필요한 경우를 생각해보세요. 이는 서비스 B뿐만 아니라 서비스 A에도 영향을 미칠 것입니다. 변경은 동일한 공유 개체를 사용하여 더 많은 서비스를 추가합니다. 불필요한 종속성이라는 단어를 사용하여 "두 번째 계층"서비스를 나타냅니다.

데이터 모델/개체는 내부 계층 데이터 개체에 매핑되어야 하는 다음 계층에만 사용되어야 합니다. 서비스 C에 변경 사항이 있는 경우 서비스 B에만 영향을 미쳐야 합니다.

이제 또 다른 예를 들어 보겠습니다. 위의 서비스가 실제로 다른 회사에서 관리되는 경우 A는 B의 클라이언트/소비자이고 B는 C의 클라이언트입니다. 귀하가 C의 소유자인 경우에만 알려야 합니다. 귀하의 클라이언트가 귀하의 API(이 경우 B)에 대한 모든 업데이트를 인식하고 클라이언트(A)의 클라이언트에 대해 생각할 필요가 없습니다.

인수 #2



Hey, but we can use Unions or any other Utilities Types in typescript be it Omit, Pick, Partial, etc



이제 C의 변경 사항을 기반으로 이러한 유형을 여전히 "재조정"해야 한다는 사실 때문에 여전히 서비스를 연결하고 있습니다.

인수 #3



Ok, what about sharing enums? Let's say there is a CreditCardType enums on payment-service which I need to reuse on my other service. Isn't it credit card type will be the same anyway?



내 제안은 특히 다른 서비스에 일종의 CreditCardType 필드가 저장되어 있는 경우 여전히 해당 열거형을 공유하지 않습니다. 분명히 동일할 수 있지만 다른 서비스에서 사용할 수 있는 것을 제한/제한하려는 사용 사례가 있을 수 있습니다.

귀하의 서비스는 다른 서비스에 불가지론적이어야 합니다(또는 다른 서비스와 명확한 책임 분리가 있어야 함). 그렇지 않은 경우 동일한 마이크로 서비스에 속해야 합니다.

결론



올바른 컨텍스트에서 사용되지 않는 경우 코드 재사용은 마이크로 서비스가 더 이상 독립적이지 않게 되므로 개발 속도를 늦추고 조정 노력을 증가시키며 진행을 방해합니다.

일부 코드 지혜 참조



“Prefer duplication over the wrong abstraction”



coding wisdom

There are two "Rules of Three" in reuse: (a) It is three times as difficult to build reusable components as single use components, and (b) a reusable component should be tried out in three different applications before it will be sufficiently general to accept into a reuse library.



Delusion of Reuse

"You want to wait until reusability becomes obvious



Premature code reuse

메모
내가 만난 더 많은 인수로 이 페이지를 계속 업데이트하려고 노력할 것입니다. 자유롭게 의견을 게시하고 다른 관점을 배우고 싶습니다 🙂

좋은 웹페이지 즐겨찾기