티스토리 뷰

[객체 지향 프로그래밍, Object-Oriented Programming, OOP]

"객체 지향 프로그래밍은 컴퓨터 프로그램들을 명령어의 목록에서 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다"

"객체 지향 프로그래밍은 프로그램을 <유연하고 변경이 용이하게 만들기 때문에> 대규모 소프트웨어 개발에 많이 사용된다." <위키피디아>

 

-> 컴퓨터 부품을 갈아끼듯이 객체를 필요에 따라 유연하게 변경하면서 개발할 수 있는 프로그래밍 방법.

 

이라고 하는데, 이정도로는 객체지향을 이해하기에 30%정도 부족한 느낌이다.

 

자바 스프링의 대가 김영한 강사님이 추천해주신 <객체지향의 사실과 오해> 책을 읽고 나서 객체지향이란 대체 멀까에 대해 정리해 보고자 한다.

 

 

1. 객체지향이란?

객체지향은 현실세계에 존재하는 여러 사물, 현상 등을 "객체"로 보고 코딩을 통해 컴퓨터 세상에서 구현하는 작업이라는 뉘앙스의 말을 한번쯤은 들어봤을 것이다. 반은 맞고 반은 틀린말이다. 현실세계의 여러 사물과 현상을 객체로 생각하는 것 까지는 맞으나, 컴퓨터 세상에서의 객체와 현실세상의 객체가 똑같이 매칭되지는 않는다.

예를들어서 통장 객체가 있다고 생각했을때, 현실세상에서는 통장 스스로는 아무것도 할 수 없지만, 컴퓨터 세상에서는 통장 객체가 잔액조회, 입출금, 초기화 등등 메소드만 만들어주면 자율적으로 행동을 수행할 수 있다. 

 

 

> 객체는 객체만의 역할과 책임(임무)을 가진다.

경찰 객체는 범인을 체포할 책임이 있고, 의사 객체는 사람을 치료할 책임이 있는 것 처럼.

 

> 또한 객체는 책임을 다하기 위해 다른 객체와 협력할 수 있다.

 

> 또한 하나의 객체는 동시에 여러 역할을 수행할 수 있다.

경찰 객체는 경찰 역할도 있지만 동시에 남자의 역할도 존재하고, 또 아빠의 역할도 동시에 존재한다.

 

> 또한 ★ 객체는 자율적이다.

택시 운전사 객체가 손님을 태우고 목적지까지 무사히 도착하라는 책임이 있다고 하자, 이 운전사는 삥땅치려고 일부러 돌아가든지, 네비를 따라가든지 자율적으로 선택할 수 있고 뭐가 어찌됐든 손님을 목적지까지 데려다주는 책임만 완수하면 된다.

책임을 수행하는 방법을 객체가 자율적으로 선택할 수 있는 것이다.

 

객체는 자율적이기 때문에 동일한 입력을 받아도 객체마다 서로 다른 방식으로 출력을 내놓을 수 있다.

이를 객체지향의 핵심인 "다형성(polymorphism)" 이라고 한다. 

 

> 역할은 다른 객체가 대체할 수 있다.

편의점 알바 객체 A가 있다고 해보자, 알바 A가 복학을 해야해서 알바를 그만두고 GC가 귀신같이 수거해 가버렸다.

그럼 점장 객체는 단순히 새로운 알바 객체 B를 뽑아서 단순히 대체하기만 하면 된다.

알바생 A와 알바생 B는 성별도 다르고 나이도 다르고 서로 다른 객체이지만 서로 동일한 역할과 책임만 수행할 수 있다면 대체해도 아무런 문제가 되지 않는다.

-> 하나의 협력 안에 여러 종류의 객체가 참여할 수 있음으로써 "추상화" 할 수 있다.

 

자율적이면서도 대체가능한 객체들의 모임이 결국 객체지향 프로그래밍의 핵심이다.

각각의 객체는 고유의 역할이 있고, 책임이 있다. 이 객체들은 각각의 책임을 다하기 위해 다른 객체들과 협력한다. 

협력하는 객체들의 모임이 바로 객체지향 프로그래밍인 것이다.

 

위에서 봤던 객체지향의 사전적 의미가 이제야 이해가 되는 기분이다.

 

"객체 지향 프로그래밍은 컴퓨터 프로그램들을 명령어의 목록에서 보는 시각에서 벗어나 여러개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다."

 

 

한줄 요약: 객체는 자율적으로 고유의 역할, 책임을 다하기 위해 서로 협력하며, 객체지향 프로그래밍이란 시스템을 상호작용하는 자율적인 객체의 공동체로 바라보고 객체들을 이용해 시스템을 구성하는 방법이다. 

 

[역할, 책임, 협력] 이 핵심이다.

 

 

- 잘 만들어진 객체지향이란 적절한 객체에 적절한 책임이 부여되어 있는 것을 말한다.

- 객체의 역할이란 관련성 높은 책임의 집합이다

- 시스템의 기능이란 객체의 연쇄적인 요청과 응답으로 구성된 협력의 결과물이다.

- 객체의 자율성은 객체의 내부와 외부를 명확하게 구분하는 것에서부터 나온다.

- 다른 객체가 "어떻게" 하는지는 전혀 중요하지 않다. "무엇을" 하는지가 핵심.

- 객체는 메시지를 통해 다른 객체에 도움을 요청한다.

- 외부에서 메시지를 받은 객체는 내부에서 정의된 메소드를 자율적으로 선택해 결과를 응답한다. (캡슐화)

 

 

객체지향은 "객체" 지향이다. 객체가 핵심이다. 클래스는 단순히 객체를 코드로 표현하는 방법일 뿐이다. 

클래스로 단순히 객체를 구현하는 것이 아니라 객체의 책임과 역할, 협력 구조에 대해 생각하는 것이 객체지향이다.

 

 

2. 객체란?

객체는 상태, 행동, 식별자를 가진다

 

1. 상태 - 객체의 상태는 단순한 값과 객체의 조합으로 나타낼 수 있다.

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

   객체의 프로퍼티는 정적인 프로퍼티와 동적인 프로퍼티 "값"으로 구분된다.

   ex) 현재 잔액, 남은 시간, 티켓 구매 유무, 백신 접종 유무 등..

   => 상태가 행동을 결정한다

 

- 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 직접적으로 변경할 수도 없다

- 외부의 객체가 간접적으로 객체의 상태를 변화시키기 위해서 필요한 것이 바로 "행동"이다.

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

 

 

2. 행동 - 객체의 행동은 상태에 영향을 끼친다. 행등을 함으로써 객체 자신과 다른 객체에 영향을 끼친다.

   => 행동이 상태를 결정한다. ★

 

- 객체의 상태는 행동에 의해서만 변경된다. 만 행동의 결과는 상태에 의존적이다.

- 객체는 자신의 상태를 외부에 노출시키지 않고 행동만 노출시킴으로써 "캡슐화"할 수 있다

-> 외부의 객체는 객체의 상태가 어떤지 알 수 없고, 알 필요도 없다. 그냥 협력을 위한 메시지만 보낼 뿐.

-> 외부의 객체는 객체가 제공하는 행동(인터페이스 or public 메소드)에만 접근할 수 있다. 그 내부의 판단은 객체가 자율적으로 한다.

 

 

3. 식별자 - 어떤 객체를 다른 객체와 구분하는데 사용되는 프로퍼티. 

- 객체는 어떤 상태에 있더라도 유일하게 식별이 가능하다. (주소, UUID 등..)

 

* 행동이 상태를 결정한다. 

- 책임 주도 설계를 따름으로써 응집도 높고 재사용성 높은 객체를 만들 수 있다.

- 객체를 설계할 때에는 상태를 먼저 결정하고 행동을 결정하는 것 보다 행동을 우선 결정하는 것이 바람직하다.

 

 

3. 추상화

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

다시말해 복잡성을 이해하기 쉬운 수준으로 단순화 하는 것이다.

- 1. 구체적인 사물간의 공통점만 취하고 자이점은 버리는 "일반화" 과정으로 단순하게 만드는 것이다

- 2. 중요한 핵심부를 강조하기 위해 불필요한 세부사항을 제거하여 단순하게 만드는 것이다

- 추상화는 목적에 의존적이다. 너무 과한 추상화는 좋지않다.

 

공통점을 기반으로 객체를 묶기 위한 그릇을 concept, 혹은 타입이라고 한다.

타입을 이용하면 객체를 여러 그룹으로 분류할 수 있으며 각 객체는 특정한 개념을 표현하는 그룹의 일원에 속한다.

 

과일 타입 속에 사과 객체, 귤 객체, 바나나 객체가 속해있는 것처럼.

이때의 객체들을 그 타입(개념)의 인스턴스라고 한다. 

 

타입을 통해 객체를 개념별로 분류할 수 있기에 추상화를 할 수 있다.

-> 동일한 책임을 수행하는 객체는 동일한 타입에 속한다.

    (객체의 타입을 결정하는 것은 객체의 행동이다. 타입은 행동에 의해 결정된다.)

-> 객체를 타입별로 묶어 공통점만 취하고 차이점은 버려 추상화한다.

-> 동일한 메시지를 수신한 객체는 자율적으로 행동하여 각기 다른 방법으로 응답한다. = "다형성"이 이뤄진다.

-> 행동에 따라 객체를 분류하기 위해서는, 객체가 외부에 제공해야 하는 행동을 먼저 고려해야한다

    (행동이 상태를 결정한다) -- 책임 주도 설계

 

타입은 일반적인 타입(일반화) 와 특수한 타입(특수화)로 나눌 수 있다.

일반 타입(Supertype)은 범용적으로 넓은 범위, 적은 행동을 가지며,

특수 타입(Subtype)은 좁은 범위, 많은 행동을 가진다.

일반 타입이 상위 인터페이스, 특수 타입이 하위 인터페이스라고 생각하면 된다.

- 서브타입은 슈퍼타입의 모든 행동을 기본적으로 가지고 있다.

- 서브타입은 슈퍼타입을 대체할 수 있다 (자식타입은 부모타입을 대체할 수 있다)

 

 

- 객체의 책임이란 외부에서 접근가능한 공용 서비스의 관점이다.

-> 즉 책임은 객체의 외부에 제공해줄 수 있는 서비스의 목록이다. = public interface를 이룬다

 

<객체지향 설계의 올바른 흐름>

 

1. 견고하고 깔끔한 협력을 설계한다

- 설계에 참여하는 객체들이 주고받을 요청과 응답의 흐름을 결정한다

- 요청과 응답의 흐름이 자연스럽게 객체에 책임을 부여한다

 

2. 객체에 부여된 책임은 객체가 외부에 제공해야 할 행동이 된다. 

- 객체가 책임을 다하기 위해 해야할 행동을 고려한다.

- public interface 구성

 

3. 객체의 행동을 결정한 후에 그를 바탕으로 행동에 필요한 데이터, 상태를 고려한다.

- 행동이 상태를 결정한다.  

- class 객체 구성

 

자율적인 책임이란 "어떻게" 해야하는가가 아니라 "무엇을" 해야하는가를 설명한다.

지나친 추상화는 협력의 의도를 명확히 표현하지 못하고 성급한 일반화를 불러온다.

 

# 인터페이스

1. 인터페이스의 사용방법만 알고있으면 대상의 내부 구조나 동작 방법을 몰라도 상호작용이 가능하다.

2. 인터페이스가 변경되지 않고 단순히 내부 구성이나 작동방식이 변경되는 것은 인터페이스 사용자에게 아무런 영향도 끼치지 못한다.

3. 인터페이스가 동일하기만 하다면 어떤 대상과도 상호작용 할 수 있다.

 

객체의 인터페이스는 객체가 수신할 수 있는 메시지의 목록으로 채워진다.

- 객체가 메시지를 수신했을 때 적절한 객체의 책임이 수행된다.

  (메서드란, 메시지를 수신했을 때 책임을 수행하는 방법을 의미한다)

-> 메시지와 메서드의 구분은 객체를 내부/외부로 분리함으로써 다형성을 이룬다.

 

객체의 내부와 외부를 분리하라 - 인터페이스의 구현과 분리(=캡슐화)

외부: 공용 인터페이스

내부: 구현(implements) - 상태, 메서드 구현

 

-> 송신자와 수신자가 느슨한 인터페이스에 대해서만 결합되도록 한다.

-> 변경에 대한 안전지대를 만들고 객체의 자율성을 향상시킨다.

 

# 객체지향 설계의 순서

도메인 모델 분석 -> 협력관계 찾기. 메시지의 요청, 응답 흐름 파악 -> 각 객체에 책임 할당 ->공용 인터페이스 구성 -> 클래스 구현

  

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함