객체지향/객체지향의 사실과 오해

[객체지향] 3장 : 타입과 추상화

잔디🌿 2025. 2. 26. 16:06

내용

지하철을 이용하는 사람이 지하철의 지형, 축척 등을 표시한 지도를 보면 불편하다.

-> 이를 위해서 현대적인 지도(어디서 환승해야하는지, 다음 역은 어디인지를 나타내는)가 탄생함

이 지도는 실제와는 다르지만 승객이 꼭 알아야하는 사실은 무시하고, 알아야하는 사실만 정확하게 표현함으로써 더욱 편리하게 함

-> 노선을 추상화했다.

 

추상화를 통한 복잡성 극복

현실은 예측불가능하고 복잡하기 때문에 사람들은 본능적으로 이해하기 쉽고 예측 간으한 수준으로 현실을 분해하고 단순화하는 전략을 택함

즉, 추상화란 현실에서 출발하되 불필요한 부분을 도려내가면서 사물의 놀라운 본직을 드러나게 하는 과정

 

객체지향과 추상화

이상한 나라 앨리스의 예시를 다시 보면

앨리스는 트럼프카드처럼 생긴 인간의 무리를 트럼프라고 칭함으로써 객체들을 단순화한다.

앨리스가 이들을 이렇게 한 단어로 줄여 지칭할 수 있었던 이유는 이 인물들이 공통적으로 트럼프라고 했을 때 떠오르는 일반적인 외형과 행동 방식을 지니고 있기 때문이다.

 

트럼프와 같이 공통점을 기반으로 객체들을 묶기 위한 그릇을 개념이라고 한다.

개념을 이용하면 객체를 여러 그룹으로 분류할 수 있다. 따라서 개념은 공통점을 기반으로 객체를 분류할 수 있는 일종의 체라고 할 수 있다.

 

객체가 개념 그룹의 일원이 될 때 객체를 그 개념의 인스턴스라고 한다.

 

따라서 앨리스가 많은 군상들을 트럼프라고 일축했던 것 처럼 주변의 복잡한 객체들은 단순히 몇가지 개념의 인스턴스일 뿐이다.

 

어떤 객체가 개념의 일원이 되었다 -> 그 개념이 부가하는 의미를 만족시켰다.

 

객체의 분류장치로서 개념을 이야기할때는 아래 세가지 관점을 함께 언급한다.

  • 심볼 : 개념을 가르키는 간략한 이름이나 명칭(트럼프)
  • 내연 : 개념의 정의를 나타내며 내연의 의미를 활용해 개념에 속하는지 여부를 확인할 수 있다.(몸이 납작하고...)
  • 외연 : 개념에 속하는 모든 객체의 집합(정원사, 병사, 신하...)

어떤 객체를 어떤 개념으로 분류할지가 객체지향의 품질을 결정한다. 

적절하게 분리한 애플리케이션은 유지보수가 용이하고 변경에 유연하게 대처할 수 있다.

 

추상화의 첫번째 차원은 구체적인 사물 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순화하는 것

두번째 차원은 중요한 부분을 강조하기 위해 불필요한 세부사항은 제거해 단순화하는 것

 

타입

공학자들이 개념을 대체할 수 있는 용어를 만듦 -> 타입

 

타입에 속하는 객체도 타입의 인스턴스라고 한다.

 

데이터타입이 없으면 수많은 0과 1을 해석하는데 어려움이 있다. 따라서 데이터의 용도와 행동에 따라 그것들을 분류하였다.

 

예를들어,

더하거나 빼거나 곱할 수 있으면 숫자형

여러 문자로 구성되어있고, 다른 문자와 연결될 수 있으면 문자형

참 거짓으로 판별할 수 있으면 논리형으로 분류한다.

 

이 시스템의 목적은 데이터가 잘못 사용되지 않도록 제약사항을 부과하는 것이다.

 

타입에는 두가지 중요한 사실이 존재한다.

1. 데이터가 어떻게 사용되느냐(ex. 어떤 연산자를 사용하느냐)

2. 타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 철저하게 감춰진다

-> 하지만 프로그래머는 이를 몰라도 충분히 사용할 수 있다.

 

이렇게 데이터 타입을 설명한 이유는 우리가 객체를 일종의 데이터처럼 사용하기 때문이다.

객체는 행위에 따라 변할 수 있는 상태를 가지고 있다. 모든 객체의 상태를 모으면 결국 애플리케이션에서 관리해야하는 전체 데이터를 표현할 수 있다.

 

하지만 객체는 데이터가 아니다 

상태는 행동의 결과로 초래된 부수효과를 쉽게 표현하기 위해 도입한 추상적인 개념일 뿐

즉, 객체가 협력을 위해 어떤 책임을 지녀야 하는지를 결정하는 것이 객체지향 설계의 핵심이다.

 

즉 위에서 말한 중요한 사실이 여기에도 적용된다.

  1. 어떤 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동이다
  2. 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다.

 

행동이 우선이다

객체 내부의 표현 방식이 달라도 동일하게 행동한다면 그 객체들은 동일한 타입에 속한다고 할 수 있다.

객체의 타입을 결정하는 것은 객체의 행동뿐이다.

 

동일한 행동이란 동일한 책임을 의미하며, 동일한 책임이란 동일한 메세지 수신을 의미한다

-> 동일한 메세지를 수신하고 이를 처리하는게 가능하다

 

이는 다형성과도 관련있다

다형성은 같은 메세지에 대해 서로 다른 방식으로 응답하는 것! 즉, 다형적인 객체들은 동일한 메세지를 수신하기 때문에 동일한 타입에 속하게된다.

 

훌륭한 객체지향을 위해서는 외부에 행동만을 제공하고 데이터는 행동 뒤로 감추어야한다. -> 캡슐화

 

데이터가 캡슐 벽을 뚫고 객체의 인터페이스를 오염시키면 객체의 분류체계는 급격히 위험에 노출되고 결과적으로 유연하지 못한 설계를 낳는다

 

행동에 따라 객체를 분류하기 위해서는 객체가 내부적으로 관리할 데이터를 먼저 생각하는게 아니라 행동을 먼저 생각해야한다.

-> 책임 주도 설계

 

객체를 결정하는 것은 행동이다. 데이터는 단지 행동을 따를 뿐이다

 

타입의 계층

트럼프 인간은 트럼프가 할 수 있는 행동을 모두 할 수 있지만 트럼프보다 더 특화된 행동을 할 수 있다.

트럼프 인간은 트럼프보다 좀 더 특화된 행동을 하는 특수한 개념이다. 이 두 개념 사이의 관계를 일반화/특수화 관계라고 한다

 

트럼프가 트럼프 인간보다 더 일반적인 개념이고, 트럼프인간은 특수적인 개념이다

 

여기서 중요한 것은 일반화/특수화 관계를 결정하는 것은 객체의 상태를 표현하는 데이터가 아니라 행동이라는 것이다. 

 

일반적인 타입이란 특수한 타입이 가진 모든 행동들 중에서 일부 행동만을 가지는 타입을 가리킨다

 

일반적인 타입을 슈퍼타입이라고 하고 특수한 타입을 서브타입이라고 한다.

서브타입은 슈퍼타입을 대체할 수 있어야한다.

 

위의 경우 슈퍼타입을 상단에, 서브타입을 하단에 위치시키고 속이 빈 삼각형으로 연결해서 표현한다

이렇게 하면 중복된 행위를 생략할 수 있다(슈퍼타입의 행동은 서브타입에게 자동으로 상속)

 

정적모델

타입을 사용하는 이유는 인간이 다루기에 세상이 너무 복잡하기 때문

앨리스의 키가 계속 변함 하지만 모든 경우에 앨리스는 앨리스이다 -> 앨리스가 임의의 키 값을 가질 수 있다고 생각함으로써 상황을 단순화할 수 있다

타입은 시간에 따라 동적으로 변하는 앨리스의 상태를 시간과 무관한 정적의 모습으로 다룰 수 있게 해준다.

키가 얼마냐에 집중하는 것 보다 키가 변할 수 있다는 가능성에 집중하는 것이다. 

 

타입은 추상화-> 객체의 동적인 특성을 추상화하여 상태변경이라는 복잡성을 단순화한다

 

객체의 스냅샷이란?

특정 시점에 구체적으로 어떤 생태를 가지느냐를 나타낸다. -> 객체 다이어그램

실제로 객체가 살아움직이는 동안 상태가 어떻게 변하는지를 나타내는 것 -> 동적모델

 

객체가 가질 수 있는 모든 상태와 행동을 나타냄 -> 타입모델

 

클래스를 작성하는 시점에서는 시스템을 정적인 관점에서 접근하지만, 애플리케이션을 실행해 상태 변경을 추적하고 디버깅하는 것은 동적인 모델을 탐험하는 것

 

타입을 구현하는 가장 보편적인 방법은 클래스를 이용하는 것

하지만 클래스와 타입이 동일한 개념은 아니다

 

클래스는 타입 구현 외에도 코드를 재사용하는 용도로도 쓰이기 때문

 

가장 중요한 것은 객체를 분류하기 위해 타입을 결정한 후 프로그래밍 언어를 이용해 타입을 구현할 수 있는 한 가지 방법이 클래스라는 사실을 아는 것이다.

 

중요한 점

세상은 너무 복잡해서 이를 추상화를 통해 이해해야 함

타입을 결정하는 것은 데이터(상태)가 아닌 행동이다

행동이 같으면 같은 타입

설계를 할 때는 상태를 먼저 생각하는게 아니라 행동을 먼저 생각해야한다

클래스는 타입을 구현하는 한가지 방법이다

 

출처

객체지향의 사실과 오해(조영호 지음)