[오브젝트] 2장 : 객체지향 프로그래밍

Young-Jun Kim·2022년 10월 30일
0

오브젝트

목록 보기
3/3

책의 이야기

객체지향 프로그래밍을 향해

2장에서는 객체지향 프로그래밍을 적용하기 위한 개념을 다루고 있다.

협력, 객체, 클래스

  • 진정한 객체지향 패러다임으로의 전환은 클래스가 아닌 객체에 초점을 맞출 때에만 얻을 수 있다.
    • 어떤 클래스가 필요한지 고민하기 전에 어떤 객체가 필요한지 고민하라
      • 클래스는 공통적인 상태와 행동을 공유하는 객체들을 추상화한 것이다.
      • 어떤 상태와 행동을 가지는지 먼저 결정해야 한다.
  • 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 일원으로 봐야 한다.
    • 객체들의 모양과 윤곽이 잡히면 특성과 상태를 가진 객체들을 타입으로 분류하고 이 타입을 기반으로 객체를 구현하라

도메인의 구조를 따르는 프로그램 구조

  • 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 도메인이라고 부른다.
  • 요구사항과 프로그램을 객체라는 동일한 관점에서 바라볼 수 있기 때문에 도메인을 구성하는 개념들이 프로그램의 객체와 클래스로 매끄럽게 연결될 수 있다.

클래스 구현하기

  • 클래스를 구현하거나 사용할 때 가장 중요한 것은 클래스의 경계를 구분 짓는 것이다.
    • 어떤 부분을 외부에 공개하고, 어떤 부분을 감출지 결정하는 것이 중요하다.

    • 경계의 명확성이 객체와 개발자의 자율성을 보장한다.

      객체의 자유

    1. 객체가 상태와 행동을 함께 가지는 복합적인 존재다.
    2. 객체가 스스로 판단하고 행동하는 자율적인 존재다.
    • 데이터와 기능을 객체 내부로 함께 묶는 것을 캡슐화라고 부른다.
      - 접근 수정자를 통해 접근제어가 가능하다.
      - 객체를 자율적인 존재로 만들기 위해 내부에 대한 접근을 통제한다.
      - 외부에서 접근 가능한 부분을 퍼블릭 인터페이스라 부른다.
      - 외부에서 접근 불가능하고 오직 내부에서만 접근 가능한 부분을 구현이라 부른다.

      💡 인터페이스와 구현의 분리 원칙은 휼륭한 객체지향 프로그램을 만들기 위한 핵심 원칙이다.        

      프로그래머의 자유

    • 프로그래머의 역할을 클래스 작성자와 클라이언트 프로그래머로 구분하는 것이 유용하다.

    • 클라이언트 프로그래머가 숨겨놓은 부분에 접근할 수 없도록 방지함으로써 영향을 걱정하지 않고 내부 구현을 마음대로 변경할 수 있다.

      • 구현 은닉이라 부른다.
    • 클라이언트 프로그래머가 알아야할 부분이 줄어든다.

협력하는 객체들의 공동체

  • 객체지향의 장점은 객체를 이용해 도메인의 의미를 풍부하게 표현할 수 있다는 것이다.
  • 협력의 관점에서 어떤 객체가 필요한지를 결정하고, 객체를 고통 상태와 행위를 구현하기 위해 클래스를 작성한다.

협력에 관한 짧은 이야기

  • 객체는 다른 객체의 인터페이스에 공개된 행동을 수행하도록 요청할 수 있다.
  • 요청 받은 객체는 자율적인 방법에 따라 요청을 처리한 후 응답한다.
  • 객체가 다른 객체와 상화작용할 수 잇는 방법은 메시지를 전송하는 것이다. 요청이 도착할 때 메시지를 수신했다고 이야기한다.
    • 메시지를처리하기 위한 방법을 메서드라고 부른다.

상속과 다형성

컴파일 시간 의존성과 실행 시간 의존성

  • 코드의 의존성과 실행 시점의 의존성이 서로 다를 수 있다.
    • 코드를 이해하기에는 어려워진다.
    • 유연하고 확장 가능해진다.
  • 설계가 유연해질수록 코드를 이애하고 디버깅하기는 어려워진다.

차이에 의한 프로그래밍

  • 기존 클래스와 매우 흡사한 클래스를 하나 추가할 때 상속을 사용하면 기존 코드를 재사용할 수 있다.
  • 기존 클래스가 가지고 있는 모든 속성과 행동을 새로운 클래스에서 포함시킬 수 있다.
  • 부모 클래스와 다른 부분만을 추가해서 새로운 클래스를 만드는 방법을 차이에 의한 프로그래밍이라 한다.

상속과 인터페이스

  • 인터페이스는 객체가 이해할 수 있는 메시지의 목록을 정의한다.
  • 상속을 통해 자식 클래스는 부모 클래스의 인터페이스를 포함하게 된다.
  • 부모 클래스가 수신할 수 있는 모든 메시지를 수신 가능하므로 외부 객체는 동일 타입으로 간주할 수 있다.
    • 자식 클래스가 부모 클래스를 대신하는 것을 업캐스팅이라고 부른다.
      • 자동으로 타입 캐스팅 되는 것 처럼 보인다.

다형성

  • 메시지와 메서드는 다르다
  • 동일한 메시지를 전송하지만 실제로 어떤 메서드가 실행될 것인지는 메시지즐 수신하는 개체의 클래스가 무엇이냐에 따라 달라지는것을 다형성이라고 부른다.
    • 컴파일 시간 의존성과 실행 시간 의존성이 다를 수 있다는 사실을 기반으로 한다.
      • 컴파일 시간 : 초기 바인딩, 정적 바인딩
      • 실행 시간 : 지연 바인딩, 동적 바인딩
    • 객체의 타입에 따라 다르게 응답할 수 있다.
  • 상속을 이용하면 인터페이스를 공유하는 클래스들을 하나의 타입 계층으로 묶을 수 있다.
    • 다형성을 상속과 함께 언급한다.

추상화와 유연성

추상화의 힘

  • 추상화를 사용하면 세부적인 내용을 무시한 채 상위 정책을 쉽고 간단하게 표현할 수 있다.
    • 표현의 수준을 조정하는 것을 가능하게 한다.
    • 협력 흐름을 기술하는 것을 의미한다.
  • 디자인 패턴이나 프레임워크 모두 추상화를 이용해 상위 정책을 정의하는 객체지향의 메커니즘을 활용하고 있다.

유연한 설계

  • 설계가 구체적인 상황에 결합되는 것을 방지하기 때문에 추상화가 유연한 설계를 가능하게 한다.
  • 컨텍스트 독립성이라 불리는 개념은 프레임워크와 같은 유연한 설계가 필수적인 분야에서 진가를 발휘한다.

추상 클래스와 인터페이스 트레이드오프

  • 이상적으로는 인터페이스를 사용하는 설계가 좋다.
  • 현실적으로는 과하다는 생각이 들 수 있다.
  • 구현과 관련된 모든 것들이 트레이드오프의 대상이 될 수 있다.
    • 충분한 고민이 필요하다.

코드 재사용

  • 상속은 코드 재사용을 위해 널리 사용되는 방법이다.
  • 합성은 다른 객체의 인스턴스를 자신의 인스턴스 변수로 포함해서 재사용하는 방법이다.
    • 합성이 더 좋은 방법이다.

상속

  • 상속이 캡슐화를 위반한다.
    • 부모 클래스의 구현이 자식 클래스에 노출된다.
    • 부모 클래스의 변경이 자식 크래스의 변경될 확률이 있다.
  • 설계를 유연하지 못하게 만든다.
    • 부모 클래스와 자식 클래스의 관계를 컴파일 시점에 결정한다.
    • 실행 시점에 종류를 변경하는 것이 불가능하다.

합성

  • 인터페이스에 정의된 메시지를 통해서만 코드를 재사용하는 방법을 합성이라 한다.
  • 구현을 효과적으로 캡슐화 할 수 있다.
  • 인스턴스를 교체하는 것이 비교적 쉬워서 설계를 느슨하게 한다.

개발자의 이야기

나를 비롯한 자바 개발을 경험해본 개발자분들은 다들 다양한 방법으로 2장에 나온 개념을 접해본 경우가 많았다. 다만 프론트엔드 개발자분들이나 객체지향을 처음 접하는 분들이 객체 지향의 컨셉이 등장하는 이 부분에서 처음 등장하는 여러 단어에 치여 어려워 하는 경우가 많았다. 하지만 직접 경험해보면 그렇게 어려운 개념이 아니기에 빠르게 넘어간 장이었다.

profile
엉뚱한 구석이 있습니다.

0개의 댓글