본 게시물은 조영호님의 저서 오브젝트를 학습하면서 정리한 내용입니다.
객체지향 개발자라면 꼭 알아야할 내용들이 가득한 책이기 때문에 참고만하시고 반드시 책을 구매해서 읽어보길 권해드려요!
(네이버 도서 구매링크 클릭)
저작물에 대한 문제가 발생할 경우 비공개 처리하겠습니다.
객체지향 프로그래밍을 향해
협력, 객체, 클래스
- 객체지향은 객체를 지향하는 것
- 프로그램을 작성할 때 클래스를 가장 먼저 떠올릴게 아니라, 객체 자체를 지향해야 함
- 어떤 클래스가 아닌, 어떤
객체가 필요한지
를 고민하라- 객체가 어떤 상태와 행동을 가지는지 결정
- 객체를 기능 구현하기 위해 협력하는
공동체의 일원
으로 보아라- 객체를 고립된 존재로 보면 안됨
- 객체를 협력자로 바라보아야 함
- 어떤 클래스가 아닌, 어떤
도메인의 구조를 따르는 프로그램 구조
- 도메인은 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야
- 일반적으로 클래스의 이름은 대응되는 도메인 개념의 이름과 동일 또는 유사하게 지어야 함 클래스 사이의 관계도 최대한 도메인 개념의 관계와 유사하게 만들어야 함→ 프로그램 구조를 이해하기 쉽고 예상 가능하게 만들기 위함⇒ 현실의 도메인 구조와 동일하게 매핑되어 있는 클래스 구조
클래스 구현하기
- 도메인 개념들의 구조를 반영하는 적절한 클래스 구조를 만든 후 → 적절한 프로그래밍 언어로 구현
- 클래스를 구현할 때 가장 중요한 것 : 클래스 내부와 외부의 경계를 지어주는 것
- 어떤 부분을 외부에 공개할지 정하는 작업
자율적인 객체
- 객체는
상태
와행동
을 함께 가지는 복합적인 존재
- 객체는 스스로 판단하고 행동하는
자율적인 존재
⇒ 객체지향이란 객체라는 단위 안에 데이터와 기능을 한 덩어리로 묶음으로써 적절하게 표현
- 스스로
상태를 관리
하고,판단
하고,행동
하는 자율적인 객체 공동체 구성하는 것- 외부에서 객체가 어떤 상태인지, 어떤 생각을 하고있는지 알면 안 됨
- 직접적으로 개입해도 안 됨
프로그래머의 자유
- 프로그래머의 역할
- 클래스 작성자
- 프로그램에 새로운 데이터 타입 추가
- 클라이언트 프로그래머에게 필요한 만큼만 공개 (구현은닉) → 클라이언트 프로그래머에 대한 영향 최소화
- 클라이언트 프로그래머
- 클래스 작성자가 추가한 데이터 타입 사용
- 필요한 클래스들을 엮어 애플리케이션 구축
- 내부의 구현은 무시하고 인터페이스만 구현하여 프로그램 구축 → 코드를 자유롭게 수정 가능
- 클래스 작성자
- 설계가 필요한 이유는 변경을 관리하기 위함 → 파급효과를 제어, 변경으로 인한 혼란 최소화
협력하는 객체들의 공동체
- 객체지향은 도메인의 의미를 풍부하게 표현할 수 있음
- 어떤 기능을 구현하기 위해 객체들 사이에 상호작용을 함 (협력)
- 협력 중심의 프로그래밍
- 협력관점에서 어떤 객체가 필요한지 식별
- 객체들의 공통상태, 행위를 구현하기위한 클래스 작성
- 추상화, 상속, 다형성을 활용해 위임을 함 → 객체 간의 협력
- 추상클래스
- 여러 클래스의 중복 코드를 제거할 때 활용
- 실제 애플리케이션에서는 추상클래스로 직접 인스턴스를 만들 필요가 없을 때 사용 가능
- TEMPLATE METHOD 패턴
- 부모 클래스에서는 기본적인 알고리즘 흐름을 구현,
- 중간에 필요한 처리는 자식 클래스에게 위임하는 방식
- ex) 직접 계산을 수행하지 않고
discountPolicy
에게 위임
- 추상클래스
- 생성자를 통해 객체 생성시 필요한 정보를 강제함 → 온전한 객체 생성 보장
상속과 다형성
- 상속과 다형성을 사용해서 실행 시점에 의존성을 갖도록 구현
compile time 의존성 vs runtime 의존성
- 의존성을 갖는 케이스
- 어떤 클래스가 다른 클래스에 접근할 수 있도록 경로 가지고 있는 경우
- 다른 클래스의 객체의 메서드를 호출하는 경우
- 인스턴스 실행 시에 인스턴스간의 의존성 ≠ 코드 레벨에서 클래스 간의 의존성
- ex)
discountPolicy
에 의존하고 있고discountPolicy
의 상세 구현은 생성자를 통해 생성 시점에 결정됨
- 클래스 사이의 의존성과 객체 사이의 의존성은 동일하지 않음
- 클래스 사이의 의존성과 객체 사이의 의존성이 다를수록
- 코드 이해가 어려워짐 (코드의 의존성 이외의 객체의 의존성까지 파악해야하기 때문)
- 코드가 더 유연해지고 확장 가능해짐
- 유연해질수록 디버깅이 어려워짐
- 유연성을 억제할수록 디버깅은 쉬워지지만 확장 가능성과 유연성은 떨어짐
⇒ 트레이드 오프가 존재 → 무조건 유연한 것도, 무조건 읽기 좋은 것도 다 정답은 아님
차이에 의한 프로그래밍
- 보모 클래스와 다른 부분만 추가해서 새로운 클래스를 얻어내는 것을 차이에 의한 프로그래밍이라고 함
- 상속은 코드재사용에 널리 사용되는 방법
- 기존 클래스가 가지고 있는 모든 속성과 행동을 물려받음
- 기반 클래스를 통해 쉽고 빠르게 새로운 클래스를 추가할 수 있음
상속과 인터페이스
- 상속이 가치있는 이유 : 부모 클래스가 제공하는 모든 인터페이스를 자식 클래스가 물려받을 수 있는 것→ 자식클래스는 부모클래스의 모든 메시지를 수신할 수 있음 ⇒ 외부 객체가 클래스를 부모클래스와 동일한 타입으로 간주함 (업캐스팅)
- 일반적으로 코드를 재사용하기 때문에 가치있다고 보지만 이러한 관점과 거리가 있음
- 구현상속 vs 인터페이스 상속
- 구현상속 (서브클래싱) : 코드를 재사용하기 위해서 상속을 사용
- 인터페이스상속 (서브타이핑) : 인터페이스를 공유하기위해서 상속
다형성
- 메시지와 클래스가 다른 개념이라는 것에서부터 출발
- 동일한 메시지를 수신하는 클래스에 따라서 다른 방식(메서드구현체)로 실행되는 것
- 다형성으로 인해 컴파일 시간 의존성과 실행 시간 의존성이 달라짐
- 메시지와 메서드를 실행 시점에 바인딩하게 함 ( 동적바인딩 or 지연바인딩)
인터페이스와 다형성
- 순수하게 인터페이스만 공유하고 싶을 때 사용
- 구현에 대한 고려 없이 다형적인 협력에 참여하는 클래스들이 공유 가능한 외부인터페이스 정의
추상화와 유연성
추상화의 힘
- 추상화 계층만 따로 떼어 놓고 살펴 볼 수 있음 → 요구사항의 정책을 높은 수준에서 서술
- 새로운 클래스가 추가되더라도 상위 단계에서의 협력 흐름을 그대로 따름
- 설계가 유연해짐
- 구체적인 상황에 결합되는 것을 방지함
- 조건문으로 분기하거나 기존 코드를 수정하는 것이 아닌 확장할 수 있음 → 협력의 일관성을 유지하기 쉬워짐
- 컨텍스트 독립성 키워드 참고
추상 클래스와 인터페이스 트레이드오프
- 구현과 관련된 모든 것들은 트레이드오프의 대상이 됨
- 의도를 효과적으로 전달하고 코드가 명확해질 수 있지만 반대로 과잉 조치가 될 수 있음
코드 재사용
- 코드 재사용에 가장 널리 사용되는 방법은 상속
- 그렇지만 상속이 가장 좋은 방법은 아님
- 상속보다는 합성
- 합성 : 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 재사용하는 방법
상속
- 설계에 악영향
- 상속은 캡슐화를 위반함
- 부모클래스의 구현이 자식클래스에 노출됨
- 캡슐화의 약화로 인해 부모클래스와 자식클래스가 강하게 결합될 수 있음
- 설계를 유연하지 못하게 만듦
- 상속으로 인한 클래스간 관계는 컴파일 시점에 결정됨 → 실행시점에 변경하는 것이 불가능
- 상속은 캡슐화를 위반함
합성
- 인터페이스를 통해 약하게 결합
- 상속에서의 두가지 문제를 해결함
- 인터페이스 메시지를 통해 재사용하기 때문에 효과적인 캡슐화 가능
- 메시지를 통해 느슨하게 결합 → 설계 유연 해짐
코드를 재사용하기 위해선 상속보단 합성
다형성을 위해 인터페이스를 재사용하는 경우 상속과 합성을 조합해서 사용할 수 있음
'BackEnd가 좋아 > 개발서적' 카테고리의 다른 글
오브젝트 - 🦁 3. 역할, 책임, 협력 (0) | 2023.02.08 |
---|---|
오브젝트 - 📒 1. 객체, 설계 (0) | 2023.01.23 |