Bertrand Meyer (/ did)가 왜 서브 클래 싱이 "클로즈드"모듈을 확장 할 수있는 유일한 방법이라고 생각합니까?


19

Meyer의 Object-Oriented Software Construction (1988)에서 개방 / 폐쇄 원칙 을 다음과 같이 정의합니다 .

  • 확장이 가능한 모듈은 열려 있다고합니다. 예를 들어, 포함 된 데이터 구조에 필드를 추가하거나 수행하는 기능 세트에 새 요소를 추가 할 수 있어야합니다.
  • 다른 모듈에서 사용할 수있는 모듈은 닫혀 있다고합니다. 이것은 모듈에 잘 정의되고 안정적인 설명이 제공되었다고 가정합니다 (정보 숨기기의 인터페이스).

그는 계속해서 말합니다.

모듈을 다시 열면 이전 버전에 의존하기 때문에 모든 클라이언트를 다시 열어서 업데이트해야합니다. … [이 문제]는 직 / 간접 클라이언트의 변경을 트리거하여 새로운 기능 또는 데이터 요소로 모듈을 확장해야 할 때마다 발생합니다. ... 디자인과 프로그래밍에 대한 고전적인 접근 방식을 사용하면 열려 있고 닫힌 모듈을 작성할 수있는 방법이 없습니다.

이러한 딜레마에 대한 Meyer의 솔루션은 다음과 같습니다. 기존 클래스를 수정하여 라이브러리 모듈을 확장하지 마십시오. 대신 기존 클래스를 서브 클래 싱하는 새 모듈을 작성하고 새 클라이언트가 해당 새 모듈에 종속되도록하십시오.

1988 년 저는 Turbo Pascal and Blankenship Basic에서 장난감 (절차) 프로그램을 작성하고 있었고 21 세기 전문 경력은 JVM, CLR 및 동적 언어에 관한 것이므로 Meyer의 의미를 모릅니다. "디자인 및 프로그래밍에 대한 고전적인 접근 방식".

의 마이어의 하나의 구체적인 예 이유는 클라이언트 모듈 (지금은 더 많은 사례를 요구, 더 많은 회원을 보유하고 열거에서 switch 문) 재개해야 합리적인 충분히 보이지만, 그는 거의 그 주장을 정당화하지 않습니다 때마다 당신이 라이브러리에 기능을 추가 모듈의 경우 모든 클라이언트 를 업데이트해야합니다 .

이 주장이 1988 년에 자명 한 것처럼 보이는 역사적 이유가 있습니까? 예를 들어 함수 나 데이터 구조를 C 정적 라이브러리에 추가하면 이전 버전과 호환되는 API를 사용하더라도 클라이언트를 다시 컴파일해야하는 레이아웃이 변경 되었습니까? 아니면 Meyer는 API 이전 버전과의 호환성을 강화하기위한 메커니즘을 실제로 논의하고 있습니까?


3
재미있는 질문! 나는 대답은 어떻게 든 관련이있을 것입니다하는 느낌이 추상 데이터 유형 및 객체 지향 데이터 추상화 사이의 근본적인 차이 에있는 두 개의 지배적 인 데이터 추상화 메커니즘입니다, 모듈 형 프로그래밍 (Betrand 마이어는 "고전적인 접근 방식으로 참조 무엇 ") 및 객체 지향 프로그래밍 (주석을 읽으십시오!).
Jörg W Mittag

이상하다. 현실과는 모순되는 것처럼 보인다 (1988 년에도). 또한, 그의 주장 된 접근 방식은 도움이되지 않는 모듈의 확산을 초래할 것입니다.

@ dan1111 : 다중 상속 에 대한 접근 방식을 포함하지만 이에 제한되지 않는 Eiffel의 상속 접근 방식 은 C ++, Java, C # 등과 다르므로 접근 방식이 다르다는 것은 놀라운 일이 아닙니다. 그는 결국 OO에 대한 견해를 뒷받침하기 위해 에펠 탑을 개발했습니다.
Jörg W Mittag

답변:


18

내가 알 수있는 한,이 질문은 Bertrand Meyer 자신이 대답 했으며이 대답은 정확하지 않습니다. 디자인과 프로그래밍에 대한 고전적인 접근 방식을 사용하면 개방형 및 폐쇄 형 모듈을 작성할 있습니다.

이것을 찾으려면이 책의 두 번째 판 (9 년 후, 1997 년에 출판)을 공부해야합니다. 두 번째 판의 서문에 따르면 ,

업데이트가 아니라 철저한 재 작업의 결과입니다. 원본 버전의 단락은 그대로 남아 있습니다. (실제로 한 줄은 거의 없습니다.)

특히, 당신을 혼란스럽게하는 진술은 사라졌습니다. "§3.3 다섯 가지 원칙" 에는 여전히 공개 폐쇄 원칙 장이 있으며 "§14.7 상속 소개"에서이 주제에 대한 자세한 설명이 있지만 초판의 진술은 더 이상 존재하지 않습니다.

대신 기존 방식과 달리 OO 접근 방식이 더 편리하고 관용적 인 방법에 중점을 둡니다.

상속 덕분에 OO 개발자는 이전 방법으로 가능했던 것보다 훨씬 더 소프트웨어 개발에 대한 접근 방식을 채택 할 수 있습니다 ... (§3.3)

이 이중 요구 사항 (개방 및 폐쇄) 은 딜레마처럼 보이고 고전적인 모듈 구조는 실마리를 제공하지 않습니다. 그러나 상속은 그것을 해결합니다. 클래스는 컴파일, 라이브러리에 저장, 기준선 및 클라이언트 클래스에서 사용할 수 있으므로 닫힙니다. 그러나 새로운 클래스는 새로운 클래스를 추가하고 상속 된 기능을 다시 선언하여 부모로 사용할 수 있기 때문에 개방적입니다. 이 과정에서 원본을 변경하거나 고객을 방해 할 필요가 없습니다 ... (§14.7)

여기서 "고전적인 접근 방식"Meyer가 무엇을 의미하는지 궁금해하기 때문에 §4.7 Traditional Modular Structures 에서 이에 대한 설명을 찾을 수 있습니다 . 이 섹션은 이것이 "루틴 라이브러리"와 "패키지"를 의미한다고 설명합니다 (후자는 필자는이 용어가 Ada에서 가져온 것으로 CLU의 클러스터와 모듈라의 모듈 인이 기능을 가진 다른 언어를 언급합니다).

당신이 그것을 생각한다면, 이러한 접근 방법 중 어느 것도 원래 개방 폐쇄 원칙을 따르는 코드 작성을 돕기위한 것이 아닙니다. 이로 인해 저자는 다소 제 2 판에서 수정 된 조기 평가로 이어질 수 있습니다.


저자가 제 1 판과 제 2 판 사이의 진술에 대해 마음을 바꾸게 한 것은 책 자체, 즉 F 부 : 다양한 언어와 환경에서 방법 적용하기 에서 답을 찾을 수 있다고 생각 합니다. 이 장에서는 저자가 객체 지향 방법을 구식 언어로 사용하는 방법에 대해 설명합니다.

Fortran과 같은 고전적인 언어는 OO가 아니지만 여전히 사용해야하는 사람들은 이러한 오래된 접근 방식의 한계 내에서 가능한 한 많은 OO 아이디어를 적용 할 수 있습니다.

특히,이 부분에서 Meyer는 C와 심지어 포트란에서도 상속을 어떻게 구현할 수 있는지에 대해 자세히 설명합니다.

알다시피, 이것은 실제로 초판에서 그 진술을 개정 할 것을 요구합니다. 정확히 어떻게 할 있는지에 대한 현실적인 예와 함께 "고전적인 접근 방식으로 ... 어떻게 방법이 없다"고 화하는 방법을 설명하는 것은 실질적으로 불가능한 것 같습니다 .


흥미롭고, 확실히 제 2 판을 붙잡 으려고 노력해야하지만, 비 OO "고전적인"라이브러리조차도 그 기능을 방해하지 않고 (적어도 특정 종류의) 기능을 추가 할 수없는 이유는 아직 명확하지 않습니다. 고객.
David Moles

@DavidMoles는 할 있으며 내 대답의 마지막 부분은 그것을 설명하며 Meyer 자신이 (제 2 판을 위해 재 작업 할 때) 그것을 깨달았으며 어떻게 수행 할 수 있는지에 대한 예를 제공했습니다. "특히 작가가 마음을 바꾸게 한 것은 ..."etc
gnat

흠. "버전 1을 대체하고 이전 버전과 호환되는이 라이브러리의 버전 2는 보이지 않습니다. 가장 광범위한 개념적인 방법을 제외하고 다음과 같은 기능을"상속 "으로 추가합니다.
David Moles

(상속, 나에게, 해당 버전 1 버전 2로 주위이라고 여전히 의미)
데이비드 두더지

@DavidMoles는 ( 소스 코드 변경 및 재 컴파일과 같이) 버전 2로 대체 할 경우 "폐쇄 수정"으로 분류되지 않습니다. 위키피디아 기사 에서 간단히 확인할 수 있습니다. ... "
gnat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.