새소식

반응형
Study/오브젝트

[Object] 2장 : 객체지향 프로그래밍

  • -
반응형

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

진정한 객체지향 패러다임으로의 전환은 Class 가 아닌, Object에 초점을 맞출 때 에만 얻을 수 있다.

  • 어떤 클래스가 필요한지가 아니라, 어떤 객체가 필요한지 고민해야 한다.
    • 클래스는 공통적인 객체들의 상태와 행동을 추상화한 것이다.
    • 따라서 Class를 추상화시키려면 어떤 객체가 필요한지 알아야 한다.
  • 객체는 독립적인 존재가 아니다, 기능 구현을 위해 협력하는 공동체의 일원으로 봐야 한다.
    • 객체를 고립된 존재로 바라보지 말고, 협력에 참여하는 협력자로 바라봐야 한다.
    • 다른 객체에게 도움을 주거나, 의존하면서 살아가는 협력적인 존재이다.

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

도메인(domain)이란 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야

  • 객체지향 패러다임이 강력한 이유는 요구사항을 분석하는 초기 단계부터, 
  • 프로그램을 구현하는 마지막 단계까지 객체라는 동일한 추상화 기법을 사용할 수 있기 때문이다.

요구사항과 프로그램을 객체라는 동일한 관점에서 보기 때문에 

도메인을 구성하는 개념들이 프로그램의 객체와 클래스로 매끄럽게 연결된다.

일반적으로 클래스 기반의 객체지향 언어에서는 도메인 개념을 구현하기 위해 Class를 사용한다.

 

클래스 구현하기

- 클래스의 내부와 외부를 구분 

훌륭한 클래스를 설계하기 위한 핵심은 어떤 부분을 외부에 공개하고 어떤 부분을 감출지를 결정하는 것이다. 

  • 외부에서는 객체의 속성에 직접 접근할 수 없도록 막고, 
  • 적절한 public 메서드를 통해서만 내부 상태를 변경할 수 있게 해야 한다. 

경계의 명확성이 객체의 자율성을 보장 

프로그래머에게 구현의 자유를 제공 

 

- 자율적인 객체 

객체는 상태(state)와 행동(behavior)을 함께 가지는 복합적인 존재 

객체는 스스로 판단하고 행동하는 자율적인 존재 

객체지향은 객체라는 단위 안에 데이터와 기능을 한 덩어리로 묶음으로써 문제 영역의 아이디어를 적절하게 표현 

  • 캡슐화 : 데이터와 기능을 객체 내부로 함께 묶는 것
  • 접근 제어 : 대부분의 객체지향 프로그래밍 언어들은 캡슐화에서 한걸음 더 나아가 접근 제어(access control) 메커니즘도 보통 함께 제공됨
  • 접근 수정자(access modifier) : public, protected, private 등을 사용

다른 객체에게 원하는 것을 요청하고는 객체가 스스로 최선의 방법을 결정할 수 있을 것이라는 점을 믿고 기다려야 한다.

캡슐화와 접근 제어를 통해 객체를 외부에서 접근 가능한 부분(public interface)과 오직 내부에서만 접근 가능한 부분(implementation)으로 나눌 수 있다.

  • public interface(퍼블릭 인터페이스) : public으로 지정된 메서드만 포함
  • implementation(구현) : private 메서드, protected 메서드, 속성

 

- 구현 은닉

클래스 작성자(class creator) : 새로운 데이터 타입을 프로그램에 추가 

클라이언트 작성자(client programmer) : 클래스 작성자가 추가한 데이터 타입을 사용 

 

상속과 다형성

코드의 의존성(컴파일 시간 의존성)과 실행 시점의 의존성은 서로 다를 수 있다. 

유연하고, 쉽게 재사용할 수 있으며, 확장 가능한 객체지향 설계가 가지는 특징은 코드의 의존성과 실행 시점의 의존성이 다르다. 

다만, 코드의 의존성과 실행 시점의 의존성이 다르면 다를수록 코드를 이해하기는 어려워진다. 

트레이드오프 : 설계가 유연해질수록 코드를 이해하고 디버깅하기는 점점 더 어려워진다.

상속과 인터페이스 

일반적으로 대부분의 사람들은 상속의 목적이 메서드나 인스턴스 변수를 재사용하는 것이라고 생각한다. 

하지만 상속이 가치 있는 이유는 부모 클래스가 제공하는 모든 인터페이스를 자식 클래스가 물려받을 수 있기 때문이다. 

상속을 통해 자식 클래스는 부모 클래스가 수신할 수 있는 모든 메시지를 수신할 수 있다. 

  • 업캐스팅 : 자식 클래스가 부모 클래스를 대신하는 것
  • 구현 상속 : 서브클래싱(subclassing),
    • 코드를 재사용하기 위한 목적으로 상속을 사용하는 것.
    • 지양하는 것이 좋다.
  • 인터페이스 상속 : 서브타이핑(subtyping),
    • 다형적인 협력을 위해 부모 클래스와 자식 클래스가 인터페이스를 공유할 수 있도록 상속을 이용하는 것. 

상속은 구현 상속이 아니라 인터페이스 상속을 위해 사용해야 한다.

다형성 

동일한 메시지를 전송하지만 실제로 어떤 메서드가 실행될 것인지는 메시지를 수신하는 객체의 클래스가 무엇이냐에 따라 달라진다(즉, 컴파일 시간 의존성과 실행 시간 의존성이 다를 수 있다.). 

 

다형성이란 동일한 메시지를 수신했을 때 객체의 타입에 따라 다르게 응답할 수 있는 능력을 의미한다. 

  • -따라서 다형적인 협력에 참여하는 객체들은 모두 같은 메시지를 이해할 수 있어야 한다. (인터페이스가 동일해야 한다) 

상속은 인터페이스를 통일하기 위해 사용한 구현 방법 중 하나이다. 

  • 상속을 이용하면 동일한 인터페이스를 공유하는 클래스들을 하나의 타입 계층으로 묶을 수 있으므로
  • 대부분의 사람들은 다형성을 얘기할 때 상속을 함께 언급하지만,
  • 상속이 다형성을 구현할 수 있는 유일한 방법은 아니다.

다형성을 구현하는 방법은 매우 다양하지만, 메시지에 응답하기 실행될 메서드를 컴파일 시점이 아닌 실행 시점에 결정한다는 공통점이 있다.

추상화와 유연성 

추상화의 힘 

추상화 : 구현의 일부(추상 클래스인 경우) 또는 전체(자바 인터페이스 경우)를 자식 클래스가 결정할 수 있도록 결정권을 위임한다. 

  • 추상화의 계층만 따로 떼어 놓고 보면 요구사항의 정책을 높은 수준에서 서술할 수 있다.
    • 세부사항(금액 할인 정책과 비율 할인 정책을 사용한다)에 억눌리지 않고
      상위 개념(할인 정책이 존재한다)만으로 도메인의 중요한 개념을 설명할 수 있게 한다.
    • 재사용 가능한 설계의 기본을 이루는 디자인 패턴(design pattern)이나 프레임워크(framework) 모두 추상화를 이용해 상위 정책을 정의하는 객체지향의 메커니즘을 활용한다.
  • 설계가 좀 더 유연해진다.
    • 추상화를 이용해 상위 정책을 표현하면 기존 구조를 수정하지 않고도 새로운 기능을 쉽게 추가하고 확장할 수 있다.

합성 

상속은 컴파일 시점에 하나의 단위로 강하게 결합하는데(부모, 자식 코드) 반해, 합성은 클래스 간 인터페이스를 통해 약하게 결합된다.

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.