[Software Design] Class and Method Design
시작하기 전에 주의할 점은 Class와 Method design은 무조건 coding 전에 이루어져야 한다.
class가 일부 세부적으로 지정되는 동안, 먼저 class를 design하지 않고 coding에 뛰어드는 것은 크나큰 위험이 될 수도 있다.
Object를 Design 하는 것은 analysis & evolution 활동의 연장이다.
partitions, layer, classes에 대한 설명을 다음과 같이 확장한다.
- 현재 모델에 사양을 추가한다.
- reuse 할 기회를 파악한다.
- design을 재구성한다.
- design을 최적화한다.
- problem domain classes를 프로그래밍 언어로 매핑한다.
먼저, 사양을 추가하는 것을 알아보자.
현재의 analysis models의 집합을 검토한다.
포함된 모든 class는 문제를 해결하기에 필요충분조건인지 확인한다.
추가적인 또는 사용되지 않은 attribute 또는 method가 없는지 확인한다.
놓치거나 추가적인 class가 없는지 확인한다.
그리고, 클래스의 visibility를 확인해야한다.
Private는 보이지 않고, Public은 다른 class에 보인다.
Protected는 동일한 super class의 member만 볼 수 있다.
method의 signature를 결정해야한다.
method의 이름, 전달할 parameters 또는 arguments, 리턴할 값의 유형을 정해야한다.
object에 의해 보존되어야 하는 제약 조건을 정의해야한다.
전제 조건, 사후 조건, 불변 조건이 있다.
제약 조건을 위반한다면 어떻게 해야할지 결정한다.
Reuse할 기회를 확인하는 것에는 다양한 방법이 있다.
Design patterns은 일반적으로 발생하는 문제를 해결하는데 도움이되는 class 그룹이다.
Framework는 응용 프로그램의 기초를 형성하는 구현된 class의 집합이다.
Class librarie는 구현된 class의 집합이기도 하지만 framework보다 본질적으로 더 일반적이다.
Components는 특정 기능을 제공하기 위해 플러그인으로 사용되는 자체를 포함하는 class이다.
Design pattern에도 종류가 있다.
첫 번째는 Singleton pattern이다.
class에 instance가 하나만 있다는 것을 어떻게 보장할 수 있는가?
class의 유일한 instance는 어떻게 쉽게 접근할 수 있는가?
class는 어떻게 instance화를 제어할 수 있는가?
class는 instance 수를 어떻게 제한할 수 있는가?
위의 문제를 해결하기 위해 class의 생성자를 숨기거나 class의 유일한 instance를 반환하는 public static operation(getInstance())을 정의한다.
Singleton pattern 이란, 객체의 instance가 오직 1개만 생성되는 패턴을 의미한다.
두 번째는 Iterator pattern이다.
aggregate 객체의 요소는 자료 구조를 노출하지 않고 접근하고 통과해야한다.
interface를 변경하지 않고 aggregate 객체에 대해 새로운 순회 작업을 정의해야한다.
위의 문제를 해결하기 위해 aggregate 객체에 대한 접근 및 통과를 캡슐화하는 별도의 (iterator) 객체를 정의한다.
그리고, client는 iterator를 사용하여 aggregate의 표현(자료 구조)를 알지 못한 채 aggregate에 접근하고 이동한다.
마지막으로 Facade pattern이 있다.
복잡한 하위 시스템을 사용하기 쉽게 하기 위해서는 하위 시스템의 인터페이스 집합을 위한 간단한 인터페이스가 제공되어야 한다.
그리고 하위 시스템에 대한 의존성을 최소화해야 한다.
위와 같은 문제를 해결하기 위해 하위 시스템의 인터페이스와 관련하여 단순한 인터페이스를 구현한다.
그리고 요청 전달 전/후에 추가 기능을 수행할 수 있다.
design을 재구성하는 방법은 다음과 같다.
Factoring과 Normalization과 추가적인 어떤 것이 있다.
Factoring은 전체 설계를 단순화하기 위해 method 또는 class의 측면을 method와 class로 분리하는 과정을 이야기한다.
Normalization은 association class는 1 to m class로 변환되어야 하고, 모든 association과 aggregation 관계가 class의 attribute로 변환되어야 하는 것을 의미한다.
추가적인 것은 모든 상속 관계가 generalizaiton, specialization semantic만 지원하도록 보장하는 것이다.
위 그림을 예시로 보자.
(a)에서 (b)로 갈 때는 모든 class들끼리 1 to m 형태로 맞춰주기 위해서 형태가 변형되었다.
(b)에서 (c)로 갈 때는 association 되어 있는 각각의 class들의 이름이 attribute가 되어 추가되었다.
design을 최적하는 것을 알아보자.
좋은 디자인이 항상 효율로 직결된다고 생각하면 안된다.
이러한 모델들을 이해하는 것과 효율성의 균형을 잡는다.
방법은 여러가지가 있는데 다음과 같다.
object 간 접근 경로를 검토한다.
그리고 직접 fan-out(method에 의해 전송된 메시지 수), 간접 fan-out(다른 method에 의해 유도된 method에 의한 메시지 수)를 검토한다.
자주 사용하는 방법으로는 statement의 실행 순서를 고려한다.
파생된 attribute와 trigger를 생성하여 재계산을 방지한다.
일대일 association을 형성하는 class를 결합하는 것을 고려한다.
마지막으로 Problem-Domain Classes를 프로그래밍 언어로 매핑하는 것을 알아보자.
단일 상속만 지원하는 언어를 사용하는 경우 다중 상속을 제외하고, 언어가 상속을 지원하지 않는 경우 모든 상속을 제외한다.
비객체언어로 객체 지향 설계를 구현하는 것은 피한다.
Method Specification에 대한 설명은 다음과 같다.
각 method에 대한 문서 상세 내역을 이야기한다.
프로그래머가 각 method를 coding 할 수 있도록 한다.
명시적이고 명확해야한다.
공식적인 기준은 없지만, 다음 정보를 포함해야한다.
- General information (예 : method name, class name 등)
- Events : method를 불러오는 모든 항목 (예 : 마우스 클릭)
- method에 전달된 값과 method에 반환된 값을 포함하는 메시지 전달
- 알고리즘 사양
- 기타 해당 정보 (예 : 계산, 절차 호출)