추상화 기법

추상화는 도메인의 복잡성을 단순화하고 직관적인 멘탈 모델을 만드는 사용할 있는 기본적인 인지 수단이다

동일한 특성을 공유하는 객체들을 타입으로 분류하는 것이 추상화 기법의 예다.

 

추상화 기법은 결국 복잡성을 낮추기,세부사항 감추기

 

  • 분류와 인스턴스화 
    분류는 객체의 구체적인 세부 사항을 숨김, 인스턴스 간 공유하는 공통적인 특성을 기반으로 범주화
    인스턴스화는 범주로부터 객체를 생성하는 것
  • 일반화와 특수화
    범주 사이의 차이를 숨기고 번주 간에 공유하는 공통적인 특성을 강조
    이 반대가 특수화
  • 집홥과 분해
    부분과 관련된 세부 사항을 숨기고 부분을 사용해서 전체를 형성하는 과정을 가리킴
    집합의 반대 과정은 전체를 부분으로 분리하는 분해

 

 

분류와 인스턴스화

개념과 범주

 

개념이란 속성과 행위가 유사한 객체에 공통적으로 적용되는 관념이나 아이디어다 -Martin

객체를 분류하고 범주로 묶는 것은 객체들의 특정 집합에 공통의 개념을 적용하는 것을 의미한다.

 

나무라는 범주에는 '푸른 잎과 갈색의 줄기를 가진 다년생 식물'이라는 개념을 적용할 있다.

객체들을 공통적인 특성을 기반으로 범주로 묶고, 개념을 적용하는 것은 범주라는 정신적인 렌즈를 통해 세상을 바라보는 것과 유사하다.

자동차라는 렌즈를 통해 바라본 세상은 자동차 범주에 속한 객체만 보일

 

세상에 존재하는 객체에 개념을 적용하는 과정을 분류라고 한다. -Martin

분류는 객체를 특정한 개념을 가타내는 집합의 구성 요소로 포함시킨다.

 

세상에 존재하는 서로 다른 상태를 가진 무수히 많은 자동차와 나무를 개별적으로 다루기는 불가능하다. 그래서 범주로 묶어 세상이 가진 복잡성을 낮춘다.

사람들은 분류를 통해 개별 현상을 하나의 개념으로 다룬다.

이때 '수많은 개별적인 현상들' 객체라하고, '하나의 개념' 타입이라고 한다.

분류는 객체를 타입과 연관시키는 것이다.

 

분류의 역은 타입에 해당하는 객체를 생성하는 과정으로 인스턴스화 또는 예시라고 한다.

 

객체지향 세계에서 개념을 가리키는 표준 용어는 타입이다. -Martin

객체를 타입의 인스턴스라고 한다.

 

분류는 객체와 타입 간의 관계를 나타낸 것이다.

어떤 객체가 타입의 정의에 부합할 경우 객체는 해당 타입으로 분류되며 자동으로 타입의 인스턴스가 된다.

 

타입

타입을 객체의 분류 장치로서 적용할 수 있으려면 다음과 같은 세 가지 관점에서의 정의가 필요하다 - Martin
  • 심볼
    타입을 가리키는 간단략 명칭
  • 내연
    타입의 완전한 정의
  • 외연
    타입에 속하는 모든 객체들의 집합

 

 

외연과 집합

타입의 외연은 타입에 속하는 객체들의 집합으로 표현

집합 = 외연

객체들은 동시에 서로 다른 집합에 포함 수도 있다.

 

객체가 하나의 타입에 속하는 경우 단일 분류(single classification)

여러 타입에 속하는 경우 다중 분류(multiple classification) 한다.

 

대부분의 객체지향 프로그래밍 언어들은 단일 분류만을 지원한다.

대부분의 언어에서 객체는 오직 클래스의 인스턴스여야만 하며 동시에 개의 클래스의 인스턴스일 수는 없다. 관점에서 다중 분류를 다중 상속과 혼동해서는 안된다.

다중 상속은 하나의 타입이 다수의 슈퍼타입을 가질 있도록 허용하지만 타입 정의를 생략할 수는 없다. 반면 다중 분류는 특정한 타입을 정의하지 않고도 하나의 객체가 서로 다른 타입의 인스턴스가 되도록 허용한다.

 

객체를 특정한 타입으로 분류하면 해당 객체는 타입의 집합에 포함된다.

객체가 집합에서 다른 집합의 원소로 자신이 속하는 타입을 변경할 있는 경우 이를 동적 분류(dynamic classification)이라고 한다.

객체가 자신의 타입을 변경할 없는 경우 이를 정적 분류(static classification) 한다.

 

하나의 컴퓨터가 시간의 흐름에 따라 교육용 컴퓨터에서 사무용 컴퓨터로, 다시 사무용에서 교육용 컴퓨터로 분류가 바뀌는 과정은 컴퓨터가 여러 집합에 속할 있다는

 

다중 분류와 동적 분류는 서로 배타적인 개념이 아니다. 함께 적용하는 것이 실세계의 복잡성을 모델링하는데 유용하다.

 

클래스 기반의 객체지향에서 타입은 클래스로 구현된다.

대부분의 언어는 일단 클래스로부터 인스턴스를 생성한 클래스를 변경할 있는 방법을 제공하지 않는다. , 객체의 타입을 변경할 없다. 따라서 우리가 사용하는 대부분의 언어는 정적 분류만 허용하며 동적 분류를 구현할 있는 방법을 제공하지 않는다.

 

이처럼 언어의 제약으로 인해 다중 분류와 동적 분류를 구현으로 옮기기 쉽지 않다.

절충안으로 도메인 모델의 초안을 다중 분류와 동적 분류로 만들고, 실제 구현에 적합하도록 단일 분류와 정적 분류 방식으로 객체들의 범주를 재조정하는 것이 좋다.

 

디자인 템플릿은 유연성이라는 측면에서 필요한 경우에만 사용

단순함을 위해서는 단일 분류와 정적 분류를 선택

 

 

클래스

타입을 구현하는 가장 보편적인 방법

클래스는 타입 구현 용도 외에 코드 재사용 용도로 사용할 있다.

추상 클래스, 인터페이스도 타입 구현 가능

 

현재 객체지향 패러다임은 아리스토텔레스 분류법의 근간을 형성하는 아이디어를 근간으로 한다

 

아리스토 텔레스는 객체의 특성을 본질적인 속성과 우연적인 속성으로 분류했다.

본질(essence)이란 사물의 가장 핵심적이고 필수불가결한 솓성

본질적인 속성 속성을 우연적(accidental)속성이라고 한다.

예컨대 사람이 취직을 해서 회사원이 되어도 사람은 여전히 사람이다. 회사원이 사람의 본질을 바꾸지는 못한다.

 

클래스는 객체가 공유하는 본질적인 속성을 정의한다. 대부분의 객체지향 언어에는 우연적인 속성은 추가할 없다.

안타깝지만 분류 수준과 결과는 누가 분류를 하는가와 무엇을 기반으로 분류하는가에 따라 크게 달라진다. 실제로 사람들은 동일한 사물을 다양한 방식으로 인식하며 다양한 방식으로 분류한다.

 

자바스크립트처럼 클래스가 존재하지 않는 프로토타입 기반의 언어는 아리스토텔레스의 객관적인 분류 체계가 존재한다는 사상 대한 철학적 의문에 뿌리를 두고 있다. 클래스가 없는 프로토타입 언어에서 분류와 인스턴스화는 프로토타입이라는 객체의 복사를 통해 이뤄진다.

 

역할

책임의 집합이 의미하는

어떤 객체가 수행하는 책임의 집합은 객체가 협력 안에서 수행하는 역할을 암시한다.

역할은 재사용 가능하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소.

 

재사용 관점을 중심 예시

김 의사가 진료를 하다, 박 의사와 교대를 해도 의사 역할 수행에는 문제가 없다.

즉, 역할 관점에서는 변화된 것이 하나도 없다.(인터페이스라 생각해보자)

 

역할이 답이다

역할을 사용하면 하나의 협력으로 추상화 있다.

역할은 협력 내에서 다른 객체로 대체할 있다

, 역할을 대체할 있는 객체는 동일한 메시지를 이해할 있는 객체로 한정 된다.

 

메시지는 책임을 의미한다.

동일한 역할을 수행한다는 것은 협력 내에서 동일한 책임의 집합을 수행한다는 것이다.

부분은 객체지향에서 매우 중요한 개념이다.

 

역할의 개념을 사용하면 유사한 협력을 추상화해서 인지 과부하를 줄일 있다.

다양한 객체들이 동일한 협력에 참여할 있기 때문에 재사용성이 높아진다.

역할은 객체지향 설계의 단순성(simplicity), 유연성(flexibility), 재사용성(resuability) 뒷받침하는 핵심 개념이다.

 

협력의 추상화

역할의 가치는 협력을 추상화할 있다는 것이다.

협력의 개수를 줄여 보다 추상적인 역할로 단순화해 이해하기 쉬워진다.

협력의 추상화는 근본적으로 역할의 대체 가능성에서 비롯된다.

 

 

대체 가능성

객체가 역할에 주어진 책임 이외에 다른 책임을 수행할 수도 있다.

증인 역할에 모자장수는 추가 책임으로 모자 판매를

요리사도 추가 책임으로 요리를 한다.

 

객체는 역할이 암시하는 책임보다 많은 책임을 가질 있다.

따라서 대부분의 경우 객체의 타입과 역할 사이에는 일반화/특수화(추상화/구체화) 관계가 성립한다.

 

역할의 대체 가능성은 행위 호환성을 의미한다.

행위 호환성은 동일한 책임의 수행을 의미한다.

 

 

객체의 모양을 결정하는 협력

흔한 오류

데이터를 저장하기 위해 객체가 존재한다는 선입견

데이터는 객체가 행동(책임) 수행하는 필요한 재료일 뿐이다.

 

객체지향이 클래스와 클래스 간의 관계를 표현하는 정적인 측면에 중점을 둔다는 오류

중요한 것은 협력에 참여하는 동적인 객체이다.

클래스는 단지 객체를 표현하고 생성하기 위한 프로그래밍 매커니즘이다.(실제로 클래스가 없는 객체지향 언어 자바스크립트)

 

데이터나 클래스 중심으로 애플리케이션을 설계하는 오류

협력이라는 문맥을 고려하지 않고 객체를 독립적으로 보면 안된다.

 

 

협력을 따라 흐르는 객체의 책임

협력이라는 문맥 속에서 객체가 수행하게 책임(행동)결정

이후 필요한 데이터를 고민

데이터와 행동이 결정된 클래스 구현 방법 결정(책임 할당)

클래스와 데이터는 협력과 책임의 집합이 결정된 고려

 

 

객체지향 설계 기법

역할, 책임, 협력의 관점에서 애플리케이션 설계하는 유용한 가지 기법

 

책임 주도 설계(Responseibility-Driven Design) 방법

협력에 필요한 책임들을 식별, 적합한 객체에게 책임을 할당하는 방식으로 애플리케이션 설계

 

디자인 패턴(Design Pattern)

전문가들이 반복적으로 사용하는 해결 방법을 정의해 놓은 설계 템플릿의 모음

특정 문제를 해결하기 위해 이미 식별해 놓은 역할, 책임, 협력의 모음

베스트 프렉티스

 

테스트 주도 개발(Test-Driven Development)

테스트를 먼저 작성하고 테스트를 통과하는 구체적인 코드를 추가하면서 애플리케이션을 완성해가는 방식

 

책임-주도 설계

객체지향 시스템은 역할과 책임을 수행하는 자율적인 객체들의 공동체다.

 

레베카 워프스브록-책임주도설계 방법을 말한다.

 

시스템의 기능은 작은 규모의 책임으로 분할

책임은 책임을 수행할 적절한 객체에게 할당

이제 객체가 책임을 수행하는 도중 스스로 처리 못할 적절한 객체를 찾아 필요한 작업 요청(협력)

 

디자인 패턴

책임 주도 설계는 객체의 역할, 책임, 협력을 고안하기 위한 방법과 절차를 제시한다.

반면 디자인 패턴은 책임-주도 설계의 결과 표현한다.

모범이 되는 설계

 

앨리스터 코오번에 따르면 효과적으로 일하는 사람들의 가지 특징은 아무것도 없는 상태에서 작업을 시작하지 않고 이전의 훌륭한 결과물을 모방하고 약간의 수정을 거쳐 원하는 결과물을 만들어 낸다는 것이다.

패턴은 특정한 상황에서 설계를 돕기 위해 모방하고 수정할 있는 과거의 설계 경험이다.

 

디자인 패턴은 반복적으로 발생하는 문제와 문제에 대한 해법의 쌍으로 정의된다.

해결하려고하는 문제가 무엇인지 서술하고, 패턴을 적용할 있는 상황과 없는 상황을 함께 설명한다.

패턴은 반복해서 일어나는 특정한 상황에서 어떤 설계가 (why) 효과적인지에 대한 이유를 설명한다.

테스트-주도 개발

애자일 방법론의 종류인 XP 기본 프랙티스로 소개되며 주목받음

기본 흐름은 실패하는 테스트를 작성하거, 테스트를 통과하는 가장 간단한 코드를 작성한 ( 과정에서 중복은 허용된다) 리팩터링을 통해 중복을 제거하는 것이다.

테스트-주도 개발을 통해 '작동하는 깔끔한 코드' 얻을 있다.

 

테스트 주고 개발이 응집도 높고 결합도 낮은 클래스로 구성된 시스템을 개발할 있게 하는 최상의 프랙티스이지만 객체지향 초보에게는 테스트를 어떤 식으로 작성해야하는지 결정하는데 어렵다.

테스트-주도 개발은 다양한 설계 경험과 패턴에 대한 지식이 없는 사람들의 경우에는 온전한 혜택을 누리기가 어렵다.

객체지향에 대한 깊이 있는 지식을 요구한다.

개념의 가지 관점

일반적으로 객체의 분류 장치로서 개념을 이야기할 때는 아래의 가지 관점을 함께 언급한다[Martin 1998, Larman 2004]

  • 심볼 : 개념을 가리키는 간략한 이름이나 명칭
  • 내연 : 개념의 완전한 정의를 나타내며 내연의 의미를 이용해 객체가 속하는지 여부를 확인할 수 있다.
  • 외연 : 개념에 속하는 모든 객체의 집합

심볼은 예시에서 '트럼트' '토끼'

내연 예시 몸이 납작하고 손과 발이 네모난 모서리에 달려 있다는 트럼프 설명이 예시다.

외연 예시 실제 개념에 일치해 개념에 속한 객체들

 

개념이 심볼, 내연, 외연으로 구성돼 있다는 사실보다는 개념을 이용해 객체를 분류할 있다는 사실이 중요하다.

객체지향 패러다임이 복잡성을 극복하는 사용하는 가장 기본적인 인지 수단이기 때문이다.

 

객체지향의 세계에서 Class 사용한다는 사실을 감안하면

분류(Classification)라는 개념이 얼마나 중요한지 실감할 있다.

 

 

 

객체를 분류하기 위한

분류란 객체에 특정한 개념을 적용하는 작업이다. 객체에 특정한 개념을 적용하기로 결심했을 우리는 객체를 특정한 집합의 멤버로 분류하고 있는 것이다.

 

분류는 객체지향의 가장 중요한 개념 하나다.

분류가 적절치 않다면 애플리케이션 유지보수가 어렵고 변화에 쉽게 대처하지 못한다.

 

 

 

분류는 추상화를 위한 도구다

추상화 가지 차원

번째, 구체적인 사물 간의 공통점을 취하고 차이점을 버리는 일반화를 통한 단순화

번째, 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거해 단순화

 

개념을 통한 객체 분류는 추상화의 가지 차원을 모두 사용한다.

 

개념은 객체들의 복잡성을 극복하기 위한 추상화 도구다.

추상화를 사용함으로써 우리는 극도로 복잡한 세상을 그나마 제어 가능한 수준으로 단순화할 있는 것이다.

 

 

 

타입

타입은 개념이다

개념을 대체할 있는 용어를 수학에서 차용, 그것은 바로 타입(Type)

 

타입은 개념과 동일하다. 따라서 타입이란 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 있는 아이디어나 관념을 의미한다. 어떤 객체에 타입을 적용할 있을 객체를 타입의 인스턴스라고 한다. 타입의 인스턴스는 타입을 구성하는 외연인 객체 집합의 일원이 된다.

 

 

데이터 타입

실제로 컴퓨터는 01로만 이루어져 있다. 비트배열이 숫자인지 문자인지 구분이 안간다.

그래서 메모리 안에 데이터에 특정한 의미를 부여하기 시작했다. 그것이 타입 시스템(Type System)이다.

타입 시스템의 목적은 메모리 안의 모든 데이터가 비트열로 보임으로써 야기되는 혼란을 방지하는 것이다.

 

타입에 관련된 가지 중요한 사실

첫째, 타입은 데이터가 어떻게 사용되느냐에 관한 것이다.

숫자형 데이터는 연산을 있다.

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

데이터 타입의 표현은 연산 작업을 수행하기에 가장 효과적인 형태가 선택되며, 개발자는 해당 데이터 타입의 표현 방식을 몰라도 데이터를 사용하는 지장이 없다.

단지 데이터 타입을 사용하기 위해 연산자만 알고 있으면 된다.

숫자형 데이터에 산술 연산자를 알고 있다면 메모리 내부에 숫자가 어떤 방식으로 저장되는지를 모르더라도 숫자형 데이터를 사용할 있다.

 

책에서는 프로그래밍 언어 관점에서 데이터 타입을 다음과 같이 정의한다.

데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는 사용하는 메모리 집합에 관한 메타데이터. 데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 있는지를 결정한다.

 

객체와 타입

객체지향 프로그램에서 객체를 일종의 데이터처럼 사용한다.

객체를 타입에 따라 분류하고 타입에 이름을 붙이는 것은 결국 프로그램에서 사용할 새로운 데이터 타입을 선언하는 것과 같다.

 

객체는 행위에 따라 변할 있는 상태를 가지고 있다는 사실을 기억하라

 

그렇다면 객체는 데이터인가? 그렇지 않다.

다시 한번 강조하지만 객체에서 중요한 것은 객체의 행동이다.

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

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

협력은 객체간 행동으로만 이루어진다.

 

데이터 타입 가지 조언을 객체의 타입에 적용

첫째, 어떤 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동이다.

어떤 객체들이 동일한 행동을 수행할 있다면 객체들은 동일한 타입으로 분류될 있다.

둘째, 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다. 객체의 행동을 가장 효과적으로 수행할 수만 있다면 객체 내부의 상태를 어떤 방식으로 표현하더라도 무방하다.

 

 

행동이 우선이다

객체의 내부 표현 방식이 다르더라도 객체들이 동일하게 행동한다면 객체들은 동일한 타입에 속한다.

결과적으로 동일한 책임을 수행하는 일련의 객체는 동일한 타입에 속한다고 말할 있다.

객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는 아무런 영향도 미치지 않는다.(인터페이스, 다형성)

 

원칙을 다르게 해석해보자

동일한 타입에 속한 객체는 내부의 데이터 표현 방식이 다르더라도 동일한 메시지를 수신하고 이를 처리할 있다. 다만 내부의 표현 방식이 다르기 때문에 동일한 메시지를 처리하는 방식은 서로 다를 수밖에 없다.

이것은 다형성에 의미를 부여한다.

다형성은 동일한 요청에 대해 서로 다른 방식으로 응답할 있는 능력을 뜻한다.

 

데이터의 내부 표현 방식과 무관하게 행동만이 고려 대상이라는 사실은 외부에 데이터를 감춰야 한다는 것을 의미한다.

좋은 객체지향 설계는 외부에 행동만을 제공하고 데이터는 행동 뒤로 감춰야 한다.

원칙을 흔히 캡슐화라고 한다.

 

행동에 따라 객체를 분류하기 위해서는 객체가 내부적으로 관리해야 하는 데이터가 아니라 객체가 외부에 제공해야 하는 행동을 먼저 생각해야 한다. 이를 위해서는 객체가 외부에 제공해야 하는 책임을 먼저 결정하고 책임을 수행하는 적합한 데이터를 나중에 결정한 , 데이터를 책임을 수행하는 필요한 외부 인터페이스 뒤로 캡슐화해야 한다.

책임-주도 설계(Responsibility-Driven Design) 데이터-주도 설계(Data-Driven Design)방법의 단점을 개선하기 위해 고안됐다.

 

객체를 결정하는 것은 행동이다. 데이터는 단지 행동을 따를 뿐이다. 이것이 객체를 객체답게 만드는 가장 핵심적인 원칙이다.

영국에 지하철이 처음 생기고 이후 런던 지하철 노선을 쉽게 알아볼 지하철 노선도를 만들었다. 이때 실제 지형도에 맞는 위치에 구불구불한 운행 노선과 불규칙적인 간의 거리를 사실적으로 묘사했다. 결과 노선도는 매우 이해하기 어려웠다

 

지하철 노선도 디자인에서 가장 중요한 것은 얼마나 사실적으로 지형을 묘사했느냐가 아니라 역과 사이의 연결성을 얼마나 직관적으로 표현했느냐다.

해리 벡은 사실적인 지형과 축척은 무시하고 사이의 연결성에만 집중한 지하철 노선도를 창조했다. 노선도는 역의 순서와 갈아타는 역의 표시를 제외하면 어느 하나 정확한 것이 없었다. 하지만 현재까지 계속 쓰이고 있는 것은 해리 벡의 지하철 노선도다.

노선도의 핵심은 정확성을 버리고 목적에 집중한 결과다. 지하철 노선도의 목적은 지형이 아닌 연결이다.(추상화)

 

해리 벡은 지하철 승객들을 면밀하게 관찰해 승객이 알아야 하는 사실만 정확하게 표현하고 몰라도 되는 정보는 무시함으로써 이해하기 쉽고 단순하며 목적에 부합하는 지하철 노선도를 창조해 있었다.

, 지하철 노선을 추상화한 것이다.

 

 

추상화를 통한 복잡성 극복

현실은 복잡하며 예측 불가능한 혼돈의 덩어리다.

나비효과는 현실의 복잡성을 이해하고 예측하는 것이 얼마나 어려운지를 설명해 주는 적절한 메타포다.

 

인간이 지닌 인지 능력과 저장 공간은 현실의 복잡성 전부를 받아들이기에는 부족하다. 따라서 인간은 본능적으로 이해하기 쉽고 예측 가능한 수준으로 현실을 분해하고 단순화하는 전략을 따른다.

 

해리 벡이 고안한 추상화는 지형 정보를 제거하고 사이 연결성을 강조함으로써 지하철 노선도 목적에 맞게 현실을 단순화했다.

 

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

 

만약 런던 곳곳의 정확한 위치와 실제 거리를 알고자 했다면 당연히 초기 런던 지하철 노선도가 적절한 노선도이다. 중요한 것은 목적이다.

 

어떤 추상화도 의도된 목적이 아닌 다른 목적으로 사용된다면 오도될 있다.

현상은 복잡하다. 법칙은 단순하다. 버릴 무엇인지 알아내라.

 

 

이 책에서는 추상화를 다음과 같이 정의한다.

추상화

어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법이다.

 

복잡성을 다루기 위해 추상화는 두 자원에서 이뤄진다[Kramer 2007].

• 첫 번째 자원은 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만드는 것이다.

• 두 번째 자원은 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것이다.

모는 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것이라는 점을 기억하라.

 

객체지향 패러다임은 객체라는 추상화를 통해 현실의 복잡성을 극복한다.

추상화의 차원을 반드시 이해하고 적용하자

 

객체지향과 추상화

모두 트럼프일

엘리스 이야기 예시

앨리스는 분명한 경계를 가지는 식별 가능한 하나의 객체다.

3명의 정원사 역시 객체다. 클로버 병사들 역시 객체다. 하얀 토끼도 객체다.

장면에 객체는 제각기 독특한 모습을 하고 있지만, 앨리스는 객체들 대부분을 하나로 아울러 생각하고 있다. '기껏해야 트럼프에 불과해' 그렇다. 앨리스는 객체들 중에서 하얀 토끼를 제외한 모든 객체를 '트럼프'라는 하나의 개념으로 단순화해서 바라보고 있다.

과감하게 차이점을 무시하고 공통점만 취해 단순화해 버렸다.

그룹으로 나누어 단순화하기

정원사, 병사, 신하, 왕자, 공주, 하객 얼핏 보면 비슷해보이지만 인물들에게는 다양한 측면에서 서로를 구별할 있는 독특한 특징이 있다.

이처럼 명확한 경계를 가지고 서로 구별할 있는 구체적인 사람이나 사물을 객체지향 패러다임에서는 객체라고 한다.

 

앨리스는 인물들을 하나씩 살펴보면서 자신이 알고 있는 '트럼프' 의미에 적합한 인물은 '트럼프'그룹에 포함하고 이외 적합하지 않은 인물은 그룹에서 제외했다.

 

결과적으로 개의 그룹으로 나눴다. 하나는 트럼프 그룹, 나머지 하나는 토끼 그룹이다.

이제 트럼프와 토끼라는 개의 렌즈를 통해 정원을 바라보는 것은 정원에 내재된 복잡성을 효과적으로 감소시킨다.

 

개념

구체적이고 실제적인 객체들 모두를 개별적인 단위로 취급하기에는 인간이 지닌 인지능력은 턱없이 부족하다. 따라서 사람들은 본능적으로 공통적인 특성을 기준으로 객체를 여러 그룹으로 묶어 동시에 다뤄야 하는 가짓수를 줄임으로써 상황을 단순화하려고 노력한다.

 

공통점을 기반으로 객체들을 묶기 위한 그릇을 개념(concept)이라고 한다.

개념이란 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 있는 아이디어나 관념을 뜻한다.

 

개념 적용 예시

길거리를 빠른 속도로 누비는 교통수단 = 자동차 개념 적용

하늘을 나는 교통수단  = 비행기 개념 적용

 

개념을 이용하면 객체를 여러 그룹으로 분류(classification) 있다.

개념은 공통점을 기반으로 객체를 분류할 있는 일종의 체라고 있다.

 

결국 객체는 특정한 개념을 표현하는 그룹의 일원으로 포함된다.

하트 여왕은 트럼프 그룹에 일원

하얀 토끼는 토끼 그룹에 일원

이처럼 객체에 어떤 개념을 적용하는 것이 가능해서 개념 그룹의 일원이 객체를 개념의 인스턴스라고 한다.

 

객체란 특정한 개념을 적용할 있는 구체적인 사물을 의미한다. 개념이 객체에 적용됐을 객체를 개념의 인스턴스라고 한다.

 

개념은 세상의 객체들을 거르는 사용하는 렌즈를 제공한다. 렌즈를 통해 세상을 바라보면 수백 수천 개의 다양한 객체가 존재하는 복잡한 세상을 개의 개념만으로 단순화할 있다.

개념은 객체를 분류할 있는 틀을 제공한다.

 

객체지향과 인지 능력

인간은 직접적으로 지각할 있는 사물을 넘어 추상적인 사물까지도 객체로 인식할 있는 능력이 있다. 어제 주문내역과 오늘 주문내역을 구분하는 , 출금 계좌에서 동일한 입금 계좌로 동일한 금액을 이체하더라도 구분이 가능하다.

물리적인 실체는 존재하지 않더라도 인간이 쉽게 구분하고 하나의 단위로 인지할 있는 개념적인 객체의 일종이다.

 

복잡한 세상에서 인간은 단순한 객체들로 주변을 분해함으로써 세상을 이해하려고 노력한다.

, 객체란 인간이 분명하게 인지하고 구별할 있는 물리적인 또는 개념적인 경계를 지닌 어떤 이다.

 

객체지향 패러다임은 인간이 인지할 있는 다양한 객체들이 모여 현실 세계를 이루는 것처럼 소프트웨어의 세계 역시 인간이 인지할 있는 다양한 소프트웨어 객체들이 모여 이뤄져 있다는 믿음에서 출발한다.

객체지향 패더라임의 목적은 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다. 따라서 현실 세계 객체와 소프트웨어 세계의 객체와는 전혀 다른 모습을 보이는 것이 일반적이다.

 

예로 현실세계 전등은 사람없이 껏다 킬수 없다. 소프트웨어 전등은 자동으로 가능하다.

 

객체, 그리고 이상한 나라

이상한 나라의 앨리스

앨리스 이야기로 예시를 든다. 이야기 내용을 요약하면,

작은 문을 통과하기 위해, 주변 음식을 먹으면서 몸집을 줄였다가 늘렸다 한다.

앨리스 객체

앞의 이야기는 앨리스가 겪고 있는 키의 변화에 초점을 맞추고 있다.

앨리스는 정원으로 가기 위해 자신의 상태 계속 변화시켰다.

이런 상태변화는 앨리스의 행동이다. 앨리스 행동에 따라 앨리스 상태가 변한다.

 

상태를 결정하는 것은 행동이지만 행동의 결과를 결정하는 것은 상태이다.

예를들어, 앨리스 130cm 여기에 케이크를 먹어서 150cm 커졌다. 그럼 원래 상태 130cm + 150cm

280cm 된다.

, 앨리스가 행동의 결과는 앨리스의 상태에 의존적이다.

어떤 행동의 성공 여부는 이전에 어떤 행동들이 발생했는지에 영향을 받는다는 사실도 중요하다

앨리스가 문을 성공적으로 통과하기 위해서는 문을 통과할 있을 정도로 충분히 몸을 작게 중여야 한다. 따라서 앨리스는 문을 통과하기 전에 먼저 키를 작게 줄이기 위해 안의 음료나 케이크를 먹어야 한다.

이것은 행동 간의 순서가 중요하다는 것을 의미한다. 문을 통과하는 행동이 성공하려면 음료나 케이크를 먹는 행동이 선행돼야만 한다.

 

 

객체, 그리고 소프트웨어 나라

물리적인 또는 개념적인 사물은 어떤 것이라도 객체가 있다.

인간의 인지 능력 안에서 개수를 있고, 다른 사물과 구분할 있으며, 생성 시점을 있고, 독립적인 하나의 단위로 인식할 있는 모든 사물은 객체다.

 

객체의 다양한 특성을 효과적으로 설명하기 위해선 객체를 상태(state), 행동(behavior), 식별자(identity) 지닌 실체로 보는 것이 가장 효과적이다.

 

책에서 객체를 다음과 같이 정의한다.

객체란 식별 가능한 개제 또는 사물이다. 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다. 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다. 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.

 

 

상태

상태가 필요한가

객체가 주변 환경과의 상호작용에 어떻게 반응하는가는 시점까지 객체에 어떤 일이 발생했느냐에 좌우된다.

예를들어 비행기를 이용하려면 탑승 전에 발권이 필수다.

자판기에 음료를 먹기위해서는 충분한 돈을 넣어야 한다.

 

공통점은 어떤 행동의 결과는 과거에 어떤 행동들이 일어났었느냐에 의존한다는 것이다.

 

일반적으로 과거에 발생한 행동이력을 통해 현재 발생한 행동의 결과를 판단하는 방식은 복잡하고 번거롭고 이해하기 어렵다.

행동과정과 결과를 단순하게 기술하기 위한 상태라는 개념을 고안했다.

비행기 탑승 가능 여부는 항공권의 발권 상태를 보고 예측할 있다.

자판기는 현재까지 투입된 금액의 상태를 기억한다.

 

상태를 이용하면 과거의 모든 행동이력을 설명하지 않고도 행동의 결과를 쉽게 예측하고 설명할 있다.

앨리스가 과거에 어떤 행동을 했었는지 모르더라도 앨리스의 키만 알면 문을 통과할 있는지 여부를 쉽게 판단할 있다.

앨리스 키와 문높이 두가지 상태만 알면 문을 통과하는 행동의 결과를 쉽게 예측할 있다.

 

 

상태와 프로퍼티

앨리스는 객체다. 앨리스의 키를 줄이거나 늘리기 위해 사용하는 음료, 케이크, 부채, 버섯 모두 객체다. 모두 뚜렷한 경계를 가지며 식별 가능하고 상태와 행동을 지니고 있다.

 

그러나 세상에 모든 것들이 객체인 것은 아니다. 앨리스의 '' 위치' 객체가 아니다. 음료의 '' 객체가 아니다. 문이 열렸는지 '여부' 객체가 아니다

, 숫자, 문자열, , 속도, 시간, 날짜, 참/거짓과 같은 단순한 값들은 객체가 아니다.

단순값들은 자체로 독립적인 의미를 가지기보다는 다른 객체의 특성을 표현하는데 사용된다.

 

때로는 단순한 값이 아니라 객체를 사용해 다른 객체의 상태를 표현해야 때가 있다.

앨리스가 음료를 들고 있는 상태를 표현하기 위해 /거짓이 아닌 음료 객체를 이용해 표현하는 것이다. 음료를 들고있나 없나는 음료객체와 연결됐나 안됐나로 구분한다.

결론적으로 모든 객체의 상태는 단순한 값과 객체의 조합으로 표현할 있다.

객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티(property)라고 한다.

앨리스 기준 ,위치,음료가 프로퍼티다.

일반적으로 프로퍼티는 변하지 않는 정적이다. 반면 프로퍼티의 값은 변할 있는 동적이다.

 

다른 시점에서 앨리스를 봤는데 음료와 연결이 없다. 음료를 버린 것으로 보인다.

시점에서 앨리스는 음료에 대한 상태를 모른다.

이처럼 객체와 객체 사이의 의미 있는 연결을 링크(link)라고 한다.

 

객체 사이 링크를 통해서만 요청을 주고 응답을 받을 있다.

, 링크를 통해서만 협력이 가능하다

 

객체 간의 선으로 표현되는 링크와 달리 객체를 구성하는 단순 값은 속성(attribute)이라고 한다.

따라서 앨리스의 키와 위치는 속성이다.

 

조합하면 프로퍼티는 단순 값인 속성과 객체와 연결을 가르키는 링크 조합이다.

 

이 책에서는 객체의 상태를 다음과 같이 정의하기로 한다.

상대는 특정 시점에 객체가 가지고 있는 정보의 집합으로 객체의 구조적 특징을 표현한다.

객체의 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다.

객체의 프로퍼티는 단순한 값과 다른 객체를 참조하는 링크로 구분할 수 있다.

 

객체는 자율적인 존재라는 것을 명심하라

객체지향의 세계에서 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없다.

자율적인 객체는 스스로 자신의 상태를 책임져야 한다.

외부의 객체가 직접적으로 객체의 상태를 주무를 없다면 간접적으로 객체의 상태를 변경하거나 조회 있는 방법이 필요하다.

 

행동은 다른 객체로 하여금 간접적으로 객체의 상태를 변경하는 것을 가능하게 한다.

객체지향의 기본 사상은 상태와 상태를 조작하기 위한 행동을 하나의 단위로 묶는 것이라는 점을 기억하라

객체는 스스로의 행동에 의해서만 상태가 변경되는 것을 보장함으로써 객체의 자율성을 유지한다.

 

 

 

 

 

+ Recent posts