가이드라인: 설계 패키지
주제
이해하기 쉽도록 설계 모델을 더 작은 단위로 구성할 수 있습니다.
설계 모델 요소를 패키지 및 서브시스템으로 그룹화한 다음 이러한 그룹들이 서로 관련된
방법을 표시하면 모델의 전반적인 구조를 이해하기가 훨씬 쉽습니다.
설계 서브시스템은
하나 이상의 인터페이스를 구현하는 컴포넌트로서 모델화됨을 됨을 유념하십시오.
자세한 정보는 결과물: 설계 서브시스템 및
가이드라인: 설계 서브시스템을 참조하십시오.
한편 설계 패키지는 그룹화에만 사용됩니다.
패키지에 포함된 클래스는 public 또는 private일 수 있습니다.
public 클래스는 다른 클래스에 의해 연관될 수 있습니다.
private 클래스는 패키지에 포함된 클래스에 의해서만 연관될 수 있습니다.
패키지 인터페이스는 패키지의 public 클래스로 구성됩니다.
패키지 인터페이스(public 클래스)는 분리되어 다른 패키지에서 종속성을 구현합니다.
이 방법을 사용하면, 인터페이스를 일찍 개발할 수 있고 개발자는 다른 패키지의
인터페이스 내의 변경사항에 대해서만 알면 되기 때문에
병행 개발이 단순화됩니다.
여러 가지 이유로 설계 모델을 파티션할 수 있습니다.
- 시스템이 완료되었을 때의 전달 단위, 구성 또는 순서대로 패키지 및 서브시스템을
사용할 수 있습니다.
- 자원 할당 및 여러 가지 다른 개발팀의 실력을 위해서는 다른 사이트에 있는
다른 그룹 간에 프로젝트를 나누어야 할 수 있습니다. 인터페이스가 잘 정의되어 있는 서브시스템은
제어 및 통합된 방법으로 팀 간의 작업을 분할하는 방법을 제공하여
설계 및 구현을 병렬로 진행할 수 있습니다.
- 서브시스템은 사용자 유형을 반영하는 방법으로 설계 모델을 구조화하는 데 사용됩니다.
많은 변경 요구사항은 사용자로부터 발생합니다.
- 일부 어플리케이션에서 특정 정보는 소수의 사람만 액세스할 수 있어야 합니다.
서브시스템은 필요한 영역에서 비밀을 유지할 수 있게 합니다.
- 지원 시스템을 빌드할 경우, 서브시스템 및 패키지를 사용하여 지원되는 시스템의
구조와 유사한 구조를 제공합니다.
이 방법으로 두 시스템의 유지보수를 동기화할 수 있습니다.
- 서브시스템은
다음 여러 섹션에 설명된 대로 시스템이 사용하는 기존의 제품 및 서비스를
나타내는 데 사용됩니다(예: OTS 제품 및 라이브러리).
경계 클래스가 패키지로 분배된 경우 적용할 수 있는 두 개의 다른 전략이 있습니다.
선택할 수 있는 것은 시스템 인터페이스가 향후에 많이 변경될 것인지 그렇지 않은지에 따라 다릅니다.
- 시스템 인터페이스를 바꿀 예정이거나 변경을 고려 중이라면 인터페이스를 나머지
설계 모델과 분리해야 합니다.
사용자 인터페이스가 변경되면 이러한 패키지만이 영향을 받습니다.
이러한 주요 변경사항의 예로는 행 지향 인터페이스에서 윈도우 지향 인터페이스로의
전환이 있습니다.

기본 목표가 기본 인터페이스 변경사항을 단순화하는 것이면
경계 클래스를 하나의(또는 여러) 별도의 패키지에 배치해야 합니다.
- 주요 인터페이스를 변경하지 않을 계획이면 인터페이스에 대한 변경사항보다는
시스템 서비스에 대한 변경사항이 주도적 원칙되어야 합니다.
경계 클래스는 기능적으로 관련된 엔티티 및 제어 클래스와 함께
배치되어야 합니다. 이 방법은 특정 엔티티 또는 제어 클래스가 변경될 경우 어떤 경계 클래스가
영향을 받는지를 쉽게 알 수 있습니다.

시스템의 서비스에 대한 변경사항을 단순화하기 위해
경계 클래스를 기능적으로 관련된 클래스와 함께 패키지합니다.
기능적으로 어떠한 엔티티 또는 제어 클래스에도 관련되지 않은 필수 경계는
동일한 인터페이스에 속하는 경계 클래스와 함께 별도의 패키지에 배치해야 합니다.
경계 클래스가 선택사항 서비스와 관련되어 있는 경우, 서비스를 제공하기 위해
협력하는 클래스와 함께 이를 별도의 서브시스템에 그룹화하십시오.
서브시스템은 선택사항 가능성을 주문할 때 제공되는 선택사항 컴포넌트로 맵핑됩니다.
기능적으로 관련된 각 클래스 그룹에 대한 패키지를 식별해야 합니다.
두 클래스가 기능적으로 관련되어 있는지를 판단할 때 적용할 수 있는 여러 실용적인 기준이 있습니다.
중요도가 내림차순으로 나와 있습니다.
- 한 클래스의 작동 및/또는 구조를 변경하기 위해 다른 클래스도 변경해야 할 경우,
두 클래스가 기능적으로 관련되어 있습니다.
예제
주문이라는 엔티티 클래스에 새 속성을 추가할 경우,
주문 관리자라는 제어 클래스도 갱신해야 합니다.
그러므로 이들은 주문 핸들링이라는 동일한 패키지에 속합니다.
- 한 클래스(예: 엔티티 클래스)로 시작하여 시스템에서 제거되는
영향을 검토하여 한 클래스가 다른 클래스에 관련되어
있는지를 찾아낼 수 있습니다.
클래스를 제거하면 불필요하게 되는 모든 클래스는 제거되는 클래스에
어느 정도 연관되어 있습니다.
불필요하다는 것은 클래스가 제거된 클래스에서만 사용되거나 제거된 클래스에
종속된다는 것입니다.
예제
창고 처리 시스템에 두 개의 제어 클래스인
주문 관리자 및 주문 등록자를 포함하는
주문 처리하는 패키지가 있습니다.
이 두 제어 클래스 모두 창고의 주문 처리에 관련된 서비스를 모델화합니다.
모든 주문 속성 및 관계는 주문 처리용으로만 존재하는 주문 엔티티 클래스에 의해 저장됩니다.
엔티티 클래스를 제거할 경우, 주문이 엔티티 클래스에 있을 경우에만
유용하기 때문에 주문 관리자 또는 주문 등록자에 대한 요구사항은 없습니다.
따라서 주문 엔티티 클래스는 두 제어 클래스와 동일한 패키지에 포함되어야 합니다.

시스템에서 주문을 제거하면 주문 관리자 및 주문 등록자는
불필요하기 때문에 주문과 동일한 패키지에 속합니다.
- 두 객체가 많은 수의 메시지와 상호 작용을 하거나 복잡한 상호 통신을 갖고 있을 경우 기능적으로
관련될 수 있습니다.
예제
타스크 수행자 제어 클래스는 트랜스포터 인터페이스 간에
메시지를 보내고 받습니다.
이는 동일한 패키지인 타스크 핸들링 내에 포함되어야 하는 다른 표시입니다.
- 경계 클래스의 기능이 엔티티 기능을 표시하는 것이면 경계 클래스는 기능적으로 특정
엔티티 클래스에 관련될 수 있습니다.
예제
창고 처리 시스템에서 지게차
양식 경계 클래스는 지게차 엔티티 클래스의 인스턴스를 사용자에게 제공합니다.
각 지게차는 화면에 ID 번호로 표시됩니다.
지게차에 대한 정보가 변경될 경우(예: 지게차에 이름이 제공될 경우)
경계 클래스도 변경해야 합니다.
자게차 양식은 동일한 패키지에 지게차로서 포함되어 있어야 합니다.
- 두 클래스가 동일한 액터와 상호 작용하거나 동일한 액터의 변경사항에 영향을 받을 경우
기능적으로 관련되어 있어야 합니다.
두 클래스가 동일한 액터에 관련되어 있지 않을 경우 동일한 패키지에 들어 있으면 안 됩니다.
더 중요가 이유가 있으면 마지막 규칙은 무시해도 됩니다.
예제
창고 처리 시스템에 여러 가지 클래스 중에서 타스크 수행자
제어 클래스를 포함하는 타스크 처리 패키지가 있습니다.
이것이 창고에서 지게차(pallet)를 운반할 수 있는 실제 트랜스포터인
트랜스포터 액터와 연관된 유일한 패키지입니다.
액터는 트랜스포터 인터페이스 경계 클래스를 통해
타스크 수행자 제어 클래스와 상호 작용합니다.
이 경계 클래스는 타스크 핸들링에 포함되어 있어야 합니다.

트랜스포터 인터페이스 및 타스크 수행자는
둘 다 트랜스포터 액터의 변경사항에 영향을 받기 때문에 동일한 패키지에 속합니다.
- 두 클래스가 서로 관련되어 있을 경우(연관, 총계 등) 기능적으로 연관될 수 있습니다.
물론 이 기준을 무작정 따라서는 안되지만 다른 기준이 적용되지 않을 경우에는
사용할 수 있습니다.
- 클래스는 클래스 인스턴스를 작성하는 클래스에 기능적으로 연관되어 있습니다.
이러한 두 기준은 두 클래스가 동일한 패키지에 들어 있어서는 안 되는 경우를 결정합니다.
- 다른 액터에 관련되어 있는 두 클래스는 동일한 패키지에 들어 있어서는 안 됩니다.
- 선택사항 클래스 및 필수 클래스가 동일한 패키지에 들어 있어서는 안 됩니다.
먼저 패키지의 모든 요소는 동일한 선택사항을 갖고 있어야 합니다.
필수 패키지에 선택사항 모델 요소가 들어 있어서는 안 됩니다.
예제
필수 엔티티 클래스인 품목 유형은 여러 속성 중에서
재공급 임계값이라는 속성을 가집니다.
그러나 시스템에서 재공급 기능은 선택사항입니다.
그러므로 품목은 두 개의 엔티티 클래스로 분할해야 합니다.
이 때 선택사항 클래스는 필수 클래스에 관련됩니다.
필수라고 생각되는 패키지가 선택사항이라고 생각되는 패키지에 종속되지 않을 수 있습니다.
규칙으로서 두 개의 다른 액터가 단일 패키지를 사용할 수는 없습니다.
이유는 한 액터의 작동에 생긴 변경사항이 다른 액터의 작동에 영향을 미쳐서는 안되기 때문입니다.
이러한 규칙에 대한 예외(예: 선택사항 서비스를 구성하는 패키지)가 있습니다.
이 유형의 패키지는 여러 액터가 사용하더라도 분할하면 안 됩니다.
따라서 패키지가 선택사항이지 않은 경우에만 여러 액터가 사용하는
패키지 또는 클래스를 분할하십시오.
동일한 패키지의 모든 클래스는 기능적으로 연관되어 있어야 합니다.
"기능적으로 관련된 클래스에서 패키지 찾기" 섹션에 있는 기준을 따를 경우,
한 패키지 내의 클래스는 서로 기능적으로 관련되어 있습니다.
그러나 특정 클래스는 자체에 클래스에 속하지 않는 "너무 많은" 작동 또는 관계를 포함할 수 있습니다.
다른 패키지에 속하게 될 완전히 새로운 클래스 또는 약간 다른 클래스가 되려면 클래스의 파트를 제거해야 합니다.
예제
한 패키지의 제어 클래스 작동인 A가 다른 패키지의
클래스 B에 종속되어 있어서는 안됩니다.
B 특정 작동을 분리하려면 제어 클래스 A를 두 개의 제어 클래스인
A'와 A"로 나누어야 합니다.
B 특정 작동은 B와 동일한 패키지에 들어 있는 새로운 제어 클래스인
A"에 배치됩니다. 새 클래스인 A"도
관계(예: 일반화)를 원래 객체인 A'로 가져옵니다.

B 특정 작동을 분리하기 위해 동질성이 부족한
제어 클래스 A를 두 개의 제어 클래스인 A' 및 A''로 분할합니다.
한 패키지의 클래스가 다른 패키지의 클래스에 대한 연관을 갖고 있으면 이 패키지는 서로 종속됩니다.
패키지 종속성은 패키지 간의 종속성 관계를 사용하여 모델화됩니다.
종속성 관계를 통해 중요한 변경사항에 액세스할 수 있습니다.
여러 패키지가 종속된 패키지는 패키지가 하나도 종속되지 않은 패키지보다 변경하기가 어렵습니다.
패키지 스펙 중에 이와 같은 여러 종속성이 발견되기 때문에
작업 중에 이러한 관계가 바인드됩니다.
종속성 관계에 대한 설명은 종속성을 유발한 관계에 대한 정보를 포함할 수 있습니다.
이는 유지보수하기 어려운 정보를 도입하기 때문에 정보가 타당하고 값을 갖고 있을 경우에만
수행해야 합니다.
예제
창고 처리 시스템에서 주문 처리 패키지에서
항목 처리 패키지까지 종속성 관계가 있습니다.
이 연관은 주문 처리의 주문 엔티티 클래스가 다른 패키지의
항목 유형 엔티티 클래스에 대한 연관을 갖기 때문에 발생합니다.

패키지의 두 클래스 사이에 연관이 있기 때문에
주문 처리 패키지는 항목 처리에 종속적입니다.
패키지 결합은 장점일 수도 단점일 수도 있습니다.
결합이 재사용을 나타낼 때에는 장점이고 시스템을 변경 및 전개하기 어렵게 만드는
종속성을 나타낼 때에는 단점입니다.
몇 가지 일반적인 원칙을 따를 수 있습니다.
- 패키지는 상호 결합되어서는 안 됩니다(예: 상호 종속).
두 개의 패키지가 서로 종속되어서는 안 됩니다.

이 경우에서 상호 종속성을 제거하려면 패키지를 인식해야 합니다.
- 하위 계층의 패키지는 상위 계층의 패키지에 종속되어서는 안 됩니다.
패키지는 동일한 계층 및 다음 하위 계층의 패키지에만 종속됩니다.

이 경우 기능성을 재파티션해야 합니다.
한 가지 솔루션은 인터페이스와 관련하여 종속성을 기술하고 하위 계층에 인터페이스를 구성하는 것입니다.
- 종속 작동이 모든 계층에 공통인 경우, 일반적으로 종속성은 계층을 건너뛰지 않으며
대안은 계층을 통해 pass-through 조작 호출을 단순화하는 것입니다.
- 패키지는 서브시스템에 종속적이서는 안되며 다른 패키지 또는 인터페이스에만 종속적이어야 합니다.
|