오브젝트 - 02 객체지향 프로그래밍

JooHeon·2025년 7월 22일

객체지향 프로그래밍

  • 어떤 클래스가 필요한지를 고민하기 전에 어떤 객체들이 필요한지 고민
    • 클래스는 공통적인 상태와 행동을 공유하는 객체들을 추상화
      → 객체가 어떤 상태와 행동을 가지는지 먼저 결정
    • 객체를 중심에 두는 접근 방법은 설계를 단순화하고 깔끔하게 만든다
  • 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 일원
    • 이러한 관점은 설계를 유연하고 확장 가능하게 만듬
    • 객체들의 모양과 윤곽이 잡히면 공통된 특성과 상태를 가진 객체들을 타입으로 분류

→ 훌륭한 협력이 훌륭한 객체를 낳고 훌륭한 객체가 훌륭한 클래스를 낳는다

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

  • 도메인 : 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야
  • 객체지향 패러다임에서는 요구사항과 프로그램을 객체라는 동일한 관점에서 바라볼 수 있기 때문에 도메인을 구성하는 개념들이 프로그램의 객체와 클래스로 연결될 수 있다
  • 클래스 구조는 도메인의 구조와 유사한 형태를 띠어야 한다

클래스 구현하기

  • 외부에서는 객체의 속성(property)에 직접 접근할 수 없도록 막고 적절한 메서드를 통해서만 내부 상태를 변경할 수 있게 해야 한다
    • 객체는 외부의 간섭을 최소화 해야 하며 스스로 상태를 관리하는 공동체를 구성
    • 경계(접근 제어)의 명확성이 객체의 자율성을 보장하고 프로그래머에게 구현의 자유를 제공
  • 객체는 상태(state)와 행동(behavior)을 함께 가진다
    • 데이터와 기능을 한 덩어리로 묶음으로써(캡슐화) 문제 영역의 아이디어를 제공한다
    • 외부에서 접근 가능한 부분을 퍼블릭 인터페이스(public interface)
    • 내부에서만 접근 가능한 부분을 구현(Implement)
  • 클라이언트에 필요한 부분만 공개하고 나머지는 꽁꽁 숨긴다
    • 클라이언트에 대한 영향을 걱정하지 않고 내부 구현을 변경한다(구현은닉)
    • 클라이언트가 알아야 할 지식의 양이 줄어들고 작성자는 변경의 폭이 넓어진다

→ 설계가 필요한 이유는 변경을 관리하기 위해

상속과 다형성

  • 확장 가능한 객체지향 설계는 코드의 의존성과 실행 시점의 의존성이 다르다
    • 의존하고 있는 객체의 정확한 타입을 알기 위해서는 의존성을 연결하는 부분을 봐야 함
    • 코드를 이해하기는 점점 어려워지는 반면 코드는 더 유연해지고 확장 가능
    • 설계가 유연해질수록 디버깅은 어려워지고 재사용성과 확장 가능성은 높아짐
  • 메시지 전송 시 실제로 어떤 메서드가 실행될지 객체의 클래스에 따라 달라진다(다형성)
    • 객체의 타입에 따라 다르게 응답된다
    • 컴파일 시간 의존성과 실행 시간 의존성이 다를 수 있다는 점을 이용해 서로 다른 메서드를 실행할 수 있게 한다
    • 메서드를 실행 시점에 바인딩한다 (lazy binding or dynamic binding)
  • 상속은 설계에 안 좋은 영향을 미친다
    • 부모 객체의 내부 구조를 잘 알고 있어야 하기 때문에 캡슐화를 위반한다

    • 컴파일 시점에 결정되어 설계가 유연하지 않다 (객체 생성 후에 바꾸는 게 불가능)

      → 인터페이스에 정의된 메시지를 통해서만 코드를 재사용하는 방법으로 해결(합성)

합성

  • 캡슐화가 가능하며 의존하는 인스턴스를 교체하는 것이 비교적 쉽다
    • 설계를 유연하게 하며 느슨하게 결합된다
    • 코드 재사용성을 위해서는 상속보다는 합성을 선호하는 것이 좋은 방법
  • 대부분의 설계에선 상속과 인터페이스를 함께 사용해야 한다

0개의 댓글