- 요구 사항
- 영화는 제목, 상영시간, 가격정보를 가짐
- 사용자가 실제로 예매하는 대상은 상영
- 할인은 할인 조건과 할인 정책으로 나뉨
- 할인 조건
- 순서 조건
- 기간 조건
- 할인 정책
- 금액 할인 정책
- 비율 할인 정책
- 할인 정책은 하나지만, 할인 조건은 여러개 설정 가능
- 할인 조건
-
대부분 객체지향 프로그램을 작성할 때 클래스를 결정한 후, 어떤 속성과 메서드가 필요한지 고민함
- 그런데 이렇게 하면 객체지향의 본질과 거리가 멀어짐
- 클래스가 아닌 객체에 초점을 맞춰야함
- 어떻게?
- 어떤 객체가 필요한지 고민
- 객체를 보는 방식을 제대로
- 독립적인 존재 아니고, 협력적인 존재임 → 설계를 유연하고, 확장 가능하게 만듬
-
도메인의 구조를 따르는 프로그램 구조
-
자율적인 객체
- 객체지향 프로그래밍 언어는 상태와 행동을 캡슐화하고, 접근 제어 메커니즘을 제공함
- 왜일까?
- 객체를 자율적인 존재로 만들기 위해 외부 간섭 최소화
- 인터페이스와 구현의 분리
- 왜일까?
- 객체지향 프로그래밍 언어는 상태와 행동을 캡슐화하고, 접근 제어 메커니즘을 제공함
-
프로그래머의 자유
- 객체지향 설계를 이해하기 위해서 프로그래머의 역할을 두가지로 나누는 것이 유용하다
- 클래스 작성자 : 데이터 타입 추가
- 클라이언트 프로그래머 : 데이터 타입 사용
- 이렇게 하면 접근 제어 매커니즘을 통해 내부와 외부를 명확하게 경계지어야하는 이유가 명확해짐
- 클라이언트 프로그래머에 대한 영향 걱정 안해도 되기에
- 구현 은닉은 두 역할에게 모두 유용
- 클래스 작성자는 구현 바꿀 수 있고
- 클라이언트 프로그래머는 내부 구현 몰라도 되기 때문에 내부 지식 부족해도 됨
- 객체지향 설계를 이해하기 위해서 프로그래머의 역할을 두가지로 나누는 것이 유용하다
-
협력하는 객체들의 공동체
-
협력에 관한 짧은 이야기
- 메시지와 메서드는 구분해야함
- 객체끼리 상호작용할 수 있는 유일한 방법은 메시지 전송
- 수신한 메시지를 처리하기 위한 객체 자신만의 방법이 메서드
- 메시지와 메서드를 구분에서 다형성 개념이 출발함
-
할인 요금 계산을 위한 협력
- 할인 요금 계산할 때 어떤 정책 사용할지 결정하는 코드가 없다
- 상속과 다형성을 이용했기 때문
- 할인 요금 계산할 때 어떤 정책 사용할지 결정하는 코드가 없다
-
할인 정책과 할인 조건
-
할인 정책 구성하기
- 하나의 정책에 여러 조건이 들어갈 수 있도록 구현
- 컴파일 시간 의존성과 실행시간 의존성
- 차이에 의한 프로그래밍
- 상속을 통해 기존 클래스의 속성과 행동을 물려받을 수 있음
- 이를 통해 다른 부분만 추가해서 빠르게 클래스 만들기 가능
- 상속과 인터페이스
- 상속이 가치있는 이유는 부모의 인터페이스를 모두 물려받을 수 있기 때문
- 일반적으로 상속의 가치를 코드재사용으로 알고 있지만, 아님
- 코드 재사용 목적으로 상속을 사용하면 변경에 취약한 코드 낳을 가능성 높아짐
- 부모 대신 협력이 가능하다는 것이 상속의 가치
- 다형성
- 동일한 메시지를 전송하지만 하는 객체의 클래스에 따라 실행 메서드 달라짐
- 동적 바인딩
- 동일한 인터페이스 공유하는 클래스들을 하나의 타입계층으로 묶기 가능
- 컴파일 시간 의존성과 실행시간 의존성을 다르게 만들 수 있기에 다형성이 가능
- 다형성은 꼭 상속으로만 구현할 수 있는 것은 아님
- 다양한 방법으로 다형성 구현 가능
- 동일한 메시지를 전송하지만 하는 객체의 클래스에 따라 실행 메서드 달라짐
- 인터페이스와 다형성
- 자바의 인터페이스를 통해 순수하게 인터페이스만 공유가 가능
- 이를 통해 다형성 실현 가능
-
추상화의 힘
- 추상화를 통해 요구 사항을 높은 수준에서 서술 가능
- 설계 유연해짐
-
유연한 설계
- Movie에게 할인 정책 존재 여부를 결정시키는 것은 일관성있는 협력이라고 보기 힘듬
- DiscountPolicy에서 결정하게 하자
- 추상화를 기반으로 유연한 설계를 했기 때문에 쉽게 확장이 가능했음
- Movie에게 할인 정책 존재 여부를 결정시키는 것은 일관성있는 협력이라고 보기 힘듬
-
추상 클래스와 인터페이스 트레이드 오프
-
코드 재사용
- 상속은 코드를 재사용하기 위해 널리 사용되지만, 가장 좋은 방법은 아니다
- 코드 재사용을 위해서는 합성을 사용하는 것이 더 좋다
- 합성이란, 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 재사용하는 것
- 왜 상속보다 합성이 더 좋을까?
-
합성
- 합성은 상속과는 다르게 인터페이스를 통해 약하게 결합된다
- 인터페이스에 정의된 메시지를 통해서만 코드 재사용
- 합성이 상속에 비해 좋은 점
- 구현을 효과적으로 캡슐화 가능
- 인스턴스 교체가 쉬워서 설계 유연해짐