01 영화 예매 시스템
요구사항 살펴 보기
02 객체지향 프로그래밍을 향해
객체지향 패러다임으로의 전환은 객체에 초점을 맞출 때에만 얻을 수 있다.
- 어떤 객체가 필요한지 고민할 것
- 객체는 협력하는 공동체의 일원으로 볼 것 → 설계를 유연하고 확장 가능하게 만든다.
도메인의 구조를 따르는 프로그램 구조
- 도메인
- 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야
클래스 구현하기
- 클래스의 내부와 외부를 구분해야 하는 이유
- 경계의 명확성이 객체의 자율성을 보장하기 때문 → 프로그래머에게 구현의 자유를 부여
- 자율적인 객체
- 캡슐화와 접근제어는 객체를 두 부분으로 나눈다.(인터페이스 구현의 분리)
- 프로그래머의 자유
- 클라이언트 프로그래머 → 클래스들을 엮어서 빠르고 안정적으로 구축
- 클래스 작성자 → 필요한 부분만 공개하고 나먼지는 숨김
- 구현 은닉(implementation hiding)
- 클라이언트 프로그래머 → 지식의 양을 줄일 수 있다
- 클래스 작성자 → 외부에 여향을 고려하지 않고도 내부 구현을 마음대로 변경할 수 있다.
협력하는 객체들의 공동체
협력에 관한 짧은 이야기
- 객체가 다른 객체와 상호작용할 수 있는 유일한 방법은 메시지를 전송하는 것 뿐
- 다른 객체의 요청이 도착할 떄 해당 객체가 메시지를 수신했다고 한다.
- 수신된 메시지를 처리하기 위한 자신만의 방법을 메서드라고 한다.
- 메시지(추상적), 메서드(구체적)
03 할인 요금 구하기
할인 요금 계산을 위한 협력 시작하기
- 추상화(abstraction)
- 상속(inheritance)
- 다형성
할인 정책과 할인 조건
할인 정책 구성하기
04 상속과 다형성
컴파일 시간 의존성과 실행 시간 의존성
- 코드의 의존성과 실행 시점의 의존성이 서로 다를 수 있다
- 재사용할 수 있으며, 확장 가능한 설계를 가지는 코드 → 코드의 의존성과 실행 시점의 의존성이 다르다
- 단, 코드를 이해하기 어려워 진다 → 설계가 유연해질 수록 코드를 이해하기 어려워진다.
차이에 의한 프로그래밍
- 부모 클래스와 다른 부분만을 추가해서 새로운 클래스를 쉽고 빠르게 만드는 방법
- 상속을 통한 코드 중복 제거
상속과 인터페이스
- 업캐스팅(upcasting)
- 자식 클래스가 부모 클래스를 대신하는 것
- 자식 클래스가 부모 클래스로 자동적으로 타입 캐스팅됨
다형성
- 동일한 메시지를 수신했을 떄 객체의 타입에 따라 다르게 응답할 수 있는 능력
- 메서드를 실행 시점에 결정
- 지연 바인딩(lazy binding) 또는 동적 바인딩(dynamic binding)
인터페이스와 다형성
05 추상화와 유연성
추상화의 힘
- 요구사항의 정책을 높은 수준에서 서술 가능
- 상위 개념만으로도 도메인의 중요한 개념을 설명할 수 있게 한다.
- 설계가 좀 더 유연
- 기존 구조를 수정하지 않고도 새로운 기능을 쉽게 추가하고 확장할 수 있다.
유연한 설계
추상 클래스와 인터페이스 트레이드 오프
코드 재사용
상속
- 상속이 캡슐화를 위반
- 설계를 유연하지 못하게 만든다
- 부모 클래스와 자식 클래스의 관계를 컴파일 시점에 결정
- 실행 시점에 객체의 종류에 따라 변경하는 것이 불가능
합성
- 인터페이스에 정의된 메시지를 통해서만 재사용이 가능하기 때문에 구현을 효과적으로 캡슐화 가능
- 의존하는 인터페이스를 교체하는 것이 비교적 쉽기 때문에 설계를 유연하게 만들 수 있다.