가이드라인: 일반화
일반화는 다른 클래스에서 공통 특성을 캡처하는 클래스 관계입니다. 이 가이드라인은 이 관계를 사용하는 방법을 설명합니다.
관계
기본 설명

일반화

실생활에서 많은 부분이 공통 특성을 가지고 있습니다. 예를 들어 개와 고양이 모두 동물에 해당합니다. 마찬가지로 오브젝트도 공통 특성을 가지고 있습니다. 이러한 클래스 사이에서 일반화를 사용하여 명확히 할 수 있습니다. 고유한 클래스에서 공통 특성을 추출하여 향후 시스템을 좀 더 쉽게 변경하고 유지보수할 수 있습니다.

일반화는 하나의 클래스가 다른 클래스에서 상속됨을 표시합니다. 상속 클래스를 하위라고 합니다. 상속되는 클래스를 상위라고 합니다. 상속은 상위의 정의(해당 오브젝트의 속성, 관계 또는 오퍼레이션과 같은 특성 포함)가 하위 오브젝트에서도 올바름을 의미합니다. 일반화는 하위 클래스에서 상위 클래스로 도출됩니다.

일반화는 복잡하고 다중 레벨의 상속 계층 구조를 허용하는 여러 단계에서 발생할 수 있습니다. 일반 특성은 상속 계층 구조에서 상위에 있으며 특수한 특성은 하위에 있습니다. 즉, 일반화를 사용하여 보다 일반적인 개념의 전문화를 모델링할 수 있습니다.

예제

재활용품 수집기 시스템에서 모든 클래스(캔, 병 및 나무 상자)는 서로 다른 유형의 폐품 항목을 설명합니다. 동일한 유형이라는 점을 제외하고 두 가지 공통 특성이 있습니다. 바로 높이와 중량이 이에 해당합니다. 폐품 항목이라는 별도의 클래스에서 속성 및 오퍼레이션을 통해 이 특성을 모델링할 수 있습니다. 캔, 병 및 나무 상자는 이 클래스의 특성을 상속합니다.

함께 표시된 텍스트에서 설명되는 다이어그램

캔, 병 및 나무 상자 클래스에는 높이 및 중량이라는 공통 특성이 있습니다. 각각 폐품 항목이라는 일반 개념을 전문화한 것입니다.

다중 상속

클래스는 일반적으로 하나에서만 상속하지만 다중 상속을 통해 여러 다른 클래스에서 상속할 수 있습니다.

다중 상속을 사용하는 경우 알아야 할 몇 가지 가능한 문제점이 있습니다.

  • 클래스가 여러 클래스에서 상속하는 경우 상위에서 관계, 오퍼레이션 및 속성 이름이 지정된 방법을 확인해야 합니다. 여러 상위에서 동일한 이름이 나타나는 경우 특정 상속 클래스에서의 해당 의미를 설명해야 합니다. 예를 들어 해당 선언 소스를 표시하도록 이름을 규정하는 경우가 있습니다.
  • 이때 반복된 상속을 사용하는 경우 하위가 동일한 상위에서 두 번 이상 상속합니다. 이 경우 상속 계층 구조는 아래와 같이 "마름모 모양"으로 표시됩니다.

함께 표시된 텍스트에서 설명되는 다이어그램

다중 및 반복 상속. 대화 상자에서 화면 이동 창 클래스는 창 클래스를 두 번 이상 상속합니다.

이때 제기될 수 있는 질문은 "대화 상자에서 화면 이동 창의 인스턴스에 포함된 창의 속성 사본 수는 몇 개입니까?"와 같습니다. 이때 반복 상속을 사용하는 경우 시맨틱에서 명확히 정의해야 합니다. 대부분의 경우 다중 상속을 지원하는 프로그래밍 언어로 정의됩니다.

일반적으로 다중 상속을 제어하는 프로그래밍 언어 규칙은 복잡하거나 종종 정확히 사용하기 어렵습니다. 따라서 필요한 경우에만 다중 상속을 사용하고 항상 주의를 기울이는 것이 좋습니다.

추상 및 구체적 클래스

인스턴스로 작성되지 않고 다른 클래스에서 상속하기 위해서만 존재하는 클래스를 추상 클래스라고 합니다. 실제로 인스턴스로 작성된 클래스는 구체적 클래스라고 합니다. 추상 클래스에는 사용할 수 있는 하나 이상의 하위가 있어야 함에 유의하십시오.

예제

창고 관리 시스템에서 화물 운반대는 화물 운반대의 다른 유형에서 공통된 특성을 표시하는 추상 엔티티 클래스입니다. 모두 창고의 화물 운반대 역할을 수행할 수 있는 스테이션, 운반 기기 및 저장 장치와 같은 구체적 클래스에서 상속되는 클래스입니다. 이 모든 오브젝트에는 하나의 공통 특성이 있습니다. 모두 하나 이상의 화물 운반대를 보유할 수 있다는 점입니다.

함께 표시된 텍스트에서 설명되는 다이어그램

여기 화물 운반대와 같이 상속된 클래스는 추상 클래스이며 인스턴스로 작성되지 않습니다.

사용

클래스 스테레오타입의 목적은 서로 다르기 때문에 한 클래스 스테레오타입에서 다른 스테레오타입으로 상속되는 것은 올바르지 않습니다. 예를 들어 경계 클래스가 엔티티 클래스를 상속하면 경계 클래스는 일종의 합성물이 됩니다. 따라서 스테레오타입이 동일한 클래스 사이에서만 일반화를 사용해야 합니다.

일반화를 사용하여 클래스 사이에서 두 개의 관계를 표현할 수 있습니다.

  • 하위 유형 설정, 하위가 상위의 하위 유형이 되도록 지정합니다. 하위 유형 설정은 하위가 상위의 구조 및 동작을 상속하고 하위가 상위의 유형임을 의미합니다. 즉, 하위는 모든 상황에서 모든 해당 상위에 대해 채울 수 있는 하위 유형입니다.
  • 서브클래스 설정, 하위가 상위의 서브클래스(하위 유형이 아님)가 되도록 지정합니다. 서브클래스 설정은 하위가 상위의 구조 및 동작을 상속하지만 하위가 상위의 유형이 아님을 의미합니다.

여러 클래스에서 공통된 특성을 준비하여 다른 클래스가 상속하는 별도의 클래스에 배치하여 이와 같은 관계를 작성할 수 있습니다. 또는 보다 일반적인 클래스를 전문화하는 새 클래스를 작성하고 일반 클래스에서 상속하게 하는 방법을 사용할 수 있습니다.

두 개의 변형이 동시에 발생한 경우 클래스 사이에서 올바른 상속을 설정하는 것은 어렵지 않습니다. 그러나 종종 동시에 발생하지 않는 경우 상속의 사용을 이해하도록 주의를 기울여야 합니다. 최소한 모델에서 각 상속 관계의 목적을 알아야 합니다.

다형성을 지원하는 상속

하위 유형 설정은 하위가 모든 상황에서 모든 해당 상위에 대해 채울 수 있는 하위 유형임을 의미합니다. 하위 유형 설정은 다형성의 특수한 경우이며 중요한 특성입니다. 이를 통해 상위의 잠재적인 하위를 고려하지 않고 모든 클라이언트(상위를 사용하는 오브젝트)를 디자인할 수 있기 때문입니다. 그러면 클라이언트 오브젝트가 보다 일반적이고 재사용가능해집니다. 클라이언트가 실제 오브젝트를 사용하는 경우 특정 방식으로 작동하며 항상 오브젝트가 해당 타스크를 수행함을 확인할 수 있습니다. 하위 유형 설정으로 시스템이 하위 유형 세트의 변경을 허용할 수 있습니다.

예제

창고 관리 시스템에서, 운반 기기 인터페이스 클래스는 크레인 및 트럭과 같은 모든 유형의 운송 장비와 통신하는 기본적인 기능을 정의합니다. 이 클래스에서는 다른 조작 중에서도 executeTransport를 정의합니다.

함께 표시된 텍스트에서 설명되는 다이어그램

트럭 인터페이스 및 크레인 인터페이스 클래스 모두 운반 기기 인터페이스를 상속합니다. 즉, 두 클래스의 오브젝트 모두 executeTransport 메시지에 응답합니다. 이 두 오브젝트는 언제나 운반 기기 인터페이스를 대신할 수 있으며 모든 해당 동작을 제공합니다. 따라서 기타 오브젝트(클라이언트 오브젝트)는 트럭 인터페이스 또는 크레인 인터페이스 오브젝트가 메시지에 응답하는지 확인하지 않고도 운반 기기 인터페이스 오브젝트에 메시지를 송신할 수 있습니다.

운반 기기 인터페이스 클래스는 추상입니다. 절대 인스턴스로 작성될 수 없습니다. 이때 운반 기기 인터페이스가 executeTransport 조작의 서명만 정의할 수 있는 반면, 하위 클래스는 이 조작을 구현합니다.

일부 객체 지향 언어(예: C++)는 유형 계층 구조로 클래스 계층 구조를 사용하여 디자이너가 디자인 모델에서 하위 유형을 설정하는 데 계층 구조를 사용하게 합니다. 기타 경우(예: Smalltalk-80) 컴파일하는 동안 유형을 확인하지 않습니다. 오브젝트가 수신된 메시지에 응답하지 않는 경우 오류 메시지가 생성됩니다.

유형을 확인하지 않는 언어에서도 하위 유형 관계를 표시하기 위해 일반화를 사용하는 것은 좋은 아이디어입니다. 종종 사용하는 언어와 상관없이 오브젝트 모델 및 소스 코드를 쉽게 이해하고 유지보수할 수 있도록 일반화를 사용해야 합니다. 이러한 상속이 바람직한지 여부는 프로그래밍 언어 규칙에 따라 다릅니다.

구현 재사용을 지원하는 상속

서브클래스 설정은 일반화의 재사용 측면을 구성합니다. 서브클래스 설정 시 다른 클래스에서 정의된 특성을 정의하여 재사용가능한 구현 파트를 고려하십시오. 서브클래스를 설정하면 특정 클래스를 구현할 때 수고를 줄이고 코드를 재사용할 수 있습니다.

예제

Smalltalk-80 클래스 라이브러리에서 사전 클래스는 세트에서 특성을 상속합니다.

함께 표시된 텍스트에서 설명되는 다이어그램

이때 일반화를 수행하는 이유는 사전이 세트 구현에서 저장영역 전략 및 몇 가지 일반 메소드를 재사용할 수 있기 때문입니다. 사전을 세트(키-값 쌍 포함)의 일부로 보는 경우에도 사전은 세트의 하위 유형이 아닙니다. 사전(키-값 쌍만)에 오브젝트를 추가할 수 없기 때문입니다. 사전을 사용하는 오브젝트는 실제로 세트로 인식되지 않습니다.

서브클래스 설정은 종종 이해 및 유지보수가 어려운 비논리적인 상속 계층 구조를 만듭니다. 따라서 프로그래밍 언어에서 사용하도록 다른 내용이 권장되지 않는 한, 재사용을 위해서만 상속을 사용하는 것은 좋지 않습니다. 일반적으로 이러한 유형의 재사용 유지보수는 매우 까다롭습니다. 세트 클래스의 변경은 세트 클래스를 상속하는 모든 클래스의 변경에 큰 영향을 줍니다. 이 사실을 명심하고 안정된 클래스만 상속하십시오. 실제로 상속은 세트 클래스 구현을 동결합니다. 변경에 너무 많은 비용이 들기 때문입니다.

프로그래밍 언어에서 상속

디자인에서 일반화 관계를 사용하는 경우 프로그래밍 언어에서 상속의 제안된 사용 및 시맨틱에 크게 영향을 받습니다. 객체 지향 언어는 클래스 간 상속을 지원합니다. 하지만 비객체 지향 언어는 지원하지 않습니다. 디자인 모델에서 언어 특성을 처리해야 합니다. 상속 또는 다중 상속을 지원하지 않는 언어를 사용하는 경우 구현 시 상속을 시뮬레이트해야 합니다. 이 경우 디자인 모델에서 시뮬레이션을 모델링하는 것이 좋습니다. 상속 구조를 설명할 때 일반화를 사용하지 마십시오. 일반화를 사용하여 상속 구조를 모델링한 후 구현에서 상속을 시뮬레이트하면 디자인이 손상될 수 있습니다.

상속 또는 다중 상속을 지원하지 않는 언어를 사용하는 경우 구현 시 상속을 시뮬레이트해야 합니다. 이 경우 디자인 모델에서 시뮬레이션을 모델링하는 것이 가장 좋습니다. 상속 구조를 설명할 때 일반화를 사용하지 마십시오. 일반화를 사용하여 상속 구조를 모델링한 후 구현에서 상속을 시뮬레이트만 하면 디자인이 손상될 수 있습니다.

시뮬레이션 동안 인터페이스 및 기타 오브젝트 특성를 변경해야 할 수도 있습니다. 다음 방법 중 하나로 상속을 시뮬레이트하는 것이 좋습니다.

  1. 하위에서 상위로 메시지 전달.
  2. 각 하위에서 상위 코드 중복. 이 경우 상위 클래스를 작성되지 않습니다.

예제

이 예제에서 하위는 연관 인스턴스에 해당하는 링크를 통해 상위에 메시지를 전달합니다.

함께 표시된 텍스트에서 설명되는 다이어그램

캔, 병 및 나무 상자 오브젝트에서 공통된 동작은 특수 클래스로 지정됩니다. 이 동작이 공통된 오브젝트는 폐품 항목에 메시지를 전송하여 필요한 경우 해당 동작을 수행합니다.