본문 바로가기
OOP/<오브젝트>, 조영호

2장 객체지향 프로그래밍

by 민휘 2023. 4. 29.

2장에서 기억하고 싶은 것

  • 객체지향이 강력한 이유 : 요구사항 분석부터 구현까지 도메인이라는 일관된 추상화 기법을 사용함
  • 객체 지향의 본질 : 말 그대로 ‘객체’를 지향하는 것
  • 객체지향 설계의 핵심 : 적절한 협력을 식별하고 협력에 필요한 역할을 정의한 후에 역할을 수행할 수 있는 적절한 객체에게 적절한 책임을 할당하는 것이다.
  • 캡슐화 : 절차지향 접근법과 비교했을 때 객체지향 접근법의 차이는 객체를 자율적인 존재로 만드는 것이다. 그러기 위해서는 객체가 상태와 프로세스를 함께 가지면서 자신의 상태를 자기만 변경할 수 있어야 한다.
  • 객체의 접근제어 : 객체의 캡슐화를 통해 상태를 변경할 수 있는 주체는 자신으로 제한했다. 객체들이 협력하는 과정에서 어떤 객체의 상태 변화를 기대한다면, 해당 객체에게 상태 변경을 요청해야한다. 이를 두고 구체적인 상태는 객체 내부에 은닉하고, 상태를 변경할 수 있는 메시지는 외부에 공개했다고 본다. 그래서 메시지를 퍼블릭 인터페이스라고 부른다. 구현이 내부에 숨겨졌으므로 객체 개발자는 객체 내부에서 자유롭게 구현을 변경할 수 있고, 객체 클라이언트는 퍼블릭 인터페이스만 보면 되기 때문에 객체 내부에 대해 알 필요가 없으므로 간결한 이해가 가능하다.
  • 객체 도입 tip : 비록 하나의 인스턴스 변수만 포함하더라도, 객체를 도입해 개념을 더 명시적이고 분명하게 표현한다면 전체적인 설계의 명확성과 유연성을 높일 수 있다.
  • 다형성 : 다형성은 동일한 메시지를 수신했을 때 객체의 타입에 따라 다르게 응답할 수 있는 능력을 의미한다. 다형적인 협력에 참여하는 객체는 같은 인터페이스를 공유해야 한다.
  • 메시지 ≠ 메소드 : 메시지는 협력에 참여하는 객체가 무엇을 해달라고 요청하는 방법이고, 메소드는 요청을 어떻게 처리할지 정하는 방법이다. 다형성은 동일한 메시지를 전송하더라도 실제로 어떤 메소드가 실행될지 달라지기 때문에 나오는 특성이다.
  • 다형성과 동적 바인딩 : 변경을 쉽게 반영하려면, 기존 코드는 적게 바꾸면서 새로운 코드를 만들어 연결할 수 있어야 한다. 이것이 가능하려면 컴파일 시점의 의존성(코드 상의 의존성, 즉 메시지)과 런타임 의존성(실제 실행되는 메소드)가 달라야 한다. 코드를 작성할 때는 세부 구현이 변경되더라도 영향을 받지 않도록 충분히 추상화한 메시지를 통해 의존성을 만들지만, 실제 실행될 때는 어떤 메소드가 실행될지 선택해야 한다. 이를 메시지와 메소드의 바인딩이라고 하는데, 실행 시점에 이루어져야 한다. 컴파일 시점이 아닌 실행 시점에 의존성을 결정한다고 해서 지연 바인딩, 동적 바인딩이라고 부른다.
  • 상속, 인터페이스 문법 : 상속과 인터페이스 문법이 의미 있는 이유는 객체의 퍼블릭 인터페이스를 공유하고 재사용할 수 있기 때문이다.
  • 추상화 : 개념을 표현하는 구체적인 객체를 추상화한 부모 클래스, 추상 클래스나 인터페이스를 사용하게 되면 객체의 인터페이스에 초점을 맞출 수 있다. 추상화 계층만 따로 떼어놓고 살펴보면 요구사항의 정책을 높은 수준에서 서술할 수 있다. 이 개념은 디자인 패턴이나 프레임워크 등에서 사용된다. 또한 더 유연한 설계를 얻을 수 있는데, 설계가 구체적인 상황에 결합되는 것을 방지하기 때문이다. 이를 컨텍스트 독립성이라고 부른다.
  • 상속 vs 합성 : 코드를 재사용하는 목적에서 평가해보면, 상속보다 합성이 훨씬 유연하다. 상속을 코드 재사용 목적으로 사용한다면 부모와 자식이 구현에 의해 강하게 결합된다. 반면 합성은 메시지를 통해 느슨하게 의존하므로 변경이 발생하더라도 영향을 덜 받는다.