OCP ( Open Closed Principle )와 DIP ( Dependency Inversion Princible ) 의 차이점을 이해하려고했습니다 .
지금까지 인터넷에서 수행 한 연구를 바탕으로 'DIP는 OCP를 달성 할 수있는 하나의 옵션'이라는 결론에 도달했습니다.
나는 이것에 맞습니까?
DIP를 따르지 않지만 OCP를 따르는 예를 들어 주시겠습니까?
OCP ( Open Closed Principle )와 DIP ( Dependency Inversion Princible ) 의 차이점을 이해하려고했습니다 .
지금까지 인터넷에서 수행 한 연구를 바탕으로 'DIP는 OCP를 달성 할 수있는 하나의 옵션'이라는 결론에 도달했습니다.
나는 이것에 맞습니까?
DIP를 따르지 않지만 OCP를 따르는 예를 들어 주시겠습니까?
답변:
이전에 OCP (Open-Closed Principle) vs Liskov의 대체 원칙 (LSP) 에 대한 답변을 썼 으며이 두 원칙은 서로 많은 관련이 있지만 개념적으로는 다르지만 서로 다른 개념이 다릅니다. 이 답변으로 인해 OCP에 대해 간략히 설명하고 DIP에 대해 자세히 설명합니다.
먼저 다른 원칙을 먼저 설명하여 OCP가 DIP (Dependency Inversion Principle)와 어떻게 관련되고 다른지 논의 해 보겠습니다.
Bob 아저씨의 OOD 원칙을 읽으면 DIP에 다음과 같은 내용이 표시됩니다.
concretion이 아닌 추상화에 의존하십시오.
Java의 추상화는 단순히 키워드 interface
와 abstract
키워드를 사용하여 수행되므로 코드를 따라야하는 일부 소프트웨어 엔터티에 대한 "계약"이 있습니다. 일부 프로그래밍 언어에는 코드가 따라야 할 동작을 명시 적으로 설정하는 기능이 없으므로 컴파일러가 계약을 집행하도록 도와주는 대신 추상화를보다 수동으로 수행해야합니다. 예를 들어 C ++에는 가상 메소드가있는 클래스와 Javascript와 같은 동적 프로그래밍 언어가 있습니다 .Javascript와 같은 동적 프로그래밍 언어는 객체를 동일한 방식으로 사용해야합니다 (Javascript의 경우 TypeScript로 확장되어 유형 시스템이 추가되어 도움이됩니다) 컴파일러가 확인한 계약서 작성).
이름은 "반전"이라는 용어를 포함합니다. 전통적으로 (구식의 어두운 시대에는 알지 못함) 저수준 모듈에 따라 더 높은 수준의 모듈을 가진 소프트웨어 구조를 작성했기 때문입니다. 예 ButtonAtKitchen
를 들어 KitchenLamp1
및에 대한 처리 입력 을 갖는 것이 합리적 KitchenLamp2
입니다. 불행히도 소프트웨어가 필요한 것보다 훨씬 더 구체적이었고 객체 그래프는 다음과 같습니다.
따라서 "계약"을 추가하여 소프트웨어를보다 일반적으로 만들 때. 객체 그래프의 화살표가 방향을 어떻게 "반전"시키는 지 확인하십시오. 그 주방 램프는 이제에 의존합니다 Button
. 다시 말해, 세부 사항은 이제 다른 방향이 아닌 추상화에 의존합니다.
따라서 우리는 DIP의 더 일반적인 정의를 가지고 있으며, Uncle Bob의 DIP 원본 기사 에도 자세히 설명되어 있습니다.
A. 고수준 모듈은 저수준 모듈에 의존해서는 안됩니다. 둘 다 추상화에 의존해야합니다. B. 추상화는 세부 사항에 의존해서는 안됩니다. 세부 사항은 추상화에 따라 달라집니다.
Bob 아저씨의 원칙에 따라 OCP는 다음과 같이 말합니다.
클래스 동작을 수정하지 않고 확장 할 수 있어야합니다.
이 달성의 한 예는 사용하는 것이다 전략 패턴Context
클래스가됩니다 수정 폐쇄 (즉, 당신이 전혀 내부 코드의 변경할 수 없습니다) 그러나 또한 확장 오픈 은 의존성 (즉, 전략 클래스) 협력 것을합니다.
보다 일반적인 의미에서 모든 모듈은 확장 점을 통해 확장 가능하도록 제작되었습니다.
아니 , 아니야
둘 다 추상화에 대해 논의하고 있지만 개념적으로 다릅니다. 두 가지 원칙은 하나의 특정 모듈에서 OCP와 여러 모듈에서 DIP로 서로 다른 컨텍스트를보고 있습니다. 대부분의 Gang of Four 디자인 패턴과 동시에 두 가지를 모두 달성 할 수 있지만 여전히 경로에서 벗어날 수 있습니다.
위에서 언급 한 DIP 예제에서 버튼과 주방 램프 를 사용하면 확장 할 수있는 주방 램프가 없습니다 (현재 필요로하는 요구 사항이 없음). 디자인은 OCP를 깨뜨리고 있지만 DIP를 따릅니다 .
반전 된 (그리고 고려 된) 예제는 확장 가능한 키친 램프 (확장 점이 a와 같음 LampShade
)이지만 버튼은 여전히 램프에 의존합니다 . 그것은됩니다 DIP를 파괴하지만 OCP를 다음 .
이것은 실제로 프로덕션 코드에서 종종 발생하는 것으로, 일부는 원칙을 위반할 수 있습니다. 더 큰 소프트웨어 시스템 (즉, 위의 예보다 큰 것)에서는 코드를 단순하게 유지해야하므로 한 가지 원칙을 어 기고 다른 원칙을 유지하는 것이 일반적입니다. 내 생각에 이것은 SRP (Single Responsibility Principle)와 관련된 맥락에서 작고 독립적 인 모듈에 적합합니다.
일부 모듈이 복잡해지면 모든 원칙을 염두에두고 모듈을 다시 설계하거나 잘 알려진 패턴으로 리팩토링 해야 할 가능성이 높습니다 .