본문 바로가기
  • 장원익 기술블로그
더 좋은 개발자 되기/개발자 책읽기

[개발자 책읽기] 객체지향의 사실과 오해-조영호 (1장, 협력하는 객체들의 공동체)

by Wonit 2021. 4. 6.

해당 글은 조영호님의 객체지향의 사실과 오해 역할, 책임, 협력, 관점에서 본 객체지향 라는 책을 읽고 학습한 내용을 정리 및 회고하는 글 입니다. 자세한 사항은 YES 24 객체지향의 사실과 오해 에서 확인해주세요.

객체지향의 사실과 오해 - 역할, 책임, 협력 관점에서 본 객체지향 (조영호)

  • 위키북스
  • 지은이: 조영호
  • 펴낸이: 박찬규, 엮은이: 이대엽, 디자인: 북누리
  • 1쇄 발행: 2015.06.17


 

이번 장에서 이야기하고자 하는 것

 

  • 일반적인 객체지향의 상식
    • 객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임
    • 객체지향은 실세계를 모방
    • 이러한 상식은 추상적, 철학적으로는 부합하지만, 객체지향을 분석, 설계할 때는 거리감이 있음
    • 객체지향은 실세계를 모방하는 것이 아니라 새롭게 창조하는 것
    • 오히려 적합산 사고는 객체지향은 암묵적인 약속과 협약, 계약을 기반으로한 협력으로 목적을 달성하는 과정 이라고 함
    • 우리의 세계는 대부분 개인 혼자만의 힘으로 해결할 수 있는 부분이 적음
    • 모두 협력을 통해 문제를 해결하려 하므로 이 관점에서 객체를 보는 것이 더 실세계와 연관짓기 쉬움
  • 요청과 응답으로 구성된 협력
    • 요청 : 필요한 것을 얻기 위해 다른 전문가(객체) 에게 도움을 요청
    • 응답 : 요청을 받은 전문가(객체)가 주어진 책임을 다 하여 요청자가 원하는 것을 반환
      • 이들은 연쇄적으로 작용하게 됨
      • 요청자 요청 -> 요청 -> 요청 응답자
      • 요청자 응답 <- 응답 <- 응답 응답자
    • 협력 : 이러한 요청과 응답의 과정을 통한 일련의 행위
  • 역할과 책임
    • 역할 : 사람들과 협력하는 과정 속에서 특정한 역할을 부여받음
      • 예를 들어 커피를 주문하는 고객은 돈을 지불하는 역할과 책임
      • 커피를 만드는 바리스타는 고객의 요청에 부합하는 커피를 제작하는 역할과 책임
    • 책임 : 역할이 의미적으로 내포하는 뜻으로, 특정한 역할은 특정한 책임을 수행하게 됨
    • 역할과 책임의 중요한 개념
      1. 여러 사람이 동일한 역할을 수행할 수 있음
      2. 역할은 대체 가능함
      3. 책임을 수행하는 방법은 자율적으로 선택할 수 있음
      4. 한 사람이 여러 역할을 도이에 수행할 수 있음
  • 역할, 책임, 협력
    • 이러한 역할과 책임, 협력은 결국 하나의 기능을 수행하기 위한 일련의 과정
    • 하나의 기능을 수행하기 위해서는 요청과 응답 그리고 협력이 잘 어우러져야 함
    • 어떠한 객체도 섬이 아니다 - Kent Beck
      • 하나의 기능을 수행하기 위해서는 다른 객체와 적극적으로 협력해야 함
    • 역할은 유연하고 재사용 가능한 협력 관계를 구축하는 데 중요한 설계 요소
  • 협력 속에 사는 객체
    • 객체지향을 결정하는 것은 앞서 강조한 혁할, 책임, 협력이지만 실제로 이를 수행하는 행위는 객체
    • 이러한 객체의 두 가지 중요한 덕목
      1. 객체는 충분히 협력적일 것
      2. 객체는 충분히 자율적일 것
    • 객체는 스스로가 모든 일을 수행하려 해서는 안되고, 상호 협력이 이루어져야 함
      • 그렇지 않다면 스파게티처럼 꼬인 내부 복잡성에 의해 스스로 자멸하게 됨.
    • 객체는 자기 스스로의 원칙에 따라서 스스로를 통제하고 절제할 수 있어야 함.
      • 이 원칙을 만족한다면, 우리는 그 사물을 자율적인 존재라고 함.
  • 객체는 상태와 행동을 함께지닌 자율적인 존재
    • 객체 : 상태(State) + 행동(Behavior)
      • 객체가 어떤 일을 수행할 때는 협력에 참여하기 위한 상태와 행동을 지녀야 함
    • 객체의 자율성은 객체 내부와 외부를 명확히 구분하는 것으로 부터 출발
      • 객체는 다른 객체가 무엇(what)을 수행하는지 알아야 함
      • 동시에 객체는 다른 객체가 어떻게(How) 수행하는지는 몰라야 함
  • 협력과 메시지
    • 객체는 특정 요청에 협력을 하기 위한 정보를 메시지를 통해 주고받음
    • 메시지는 요청이 있을 수 있고 응답이 있을 수 있음
    • 결국 협력은 객체와 메시지를 수신하는 객체 사이의 관계가 됨
      • 송신자 : 메시지를 전송하는 객체
      • 수신자 : 메시지를 수신사흔 객체
  • 메서드와 자율성
    • 메서드 : 객체가 수신된 메시지를 처리하는 방법
    • 외부의 요청이 무엇인지 표현하는 메시지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것이 핵심
      • 이는 캡슐화와 연관됨
  • 객체를 지향하라
    • 객체지향을 이야기할 때 보통 클래스에 초점이 맞춰짐
    • 하지만 객체지향은 클래스에 초점을 맞출게 아닌 협력과 관계에 초점을 맞춰야 함
    • 클래스는 단지 객체지향을 표현하는 도구일 뿐

객체지향의 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것

나의 해석과 회고

객체지향을 올바르게 바라보는 것을 시작으로 조영호님은 여러 이야기를 한다.


대학교 2학년때 처음으로 자바를 배우고 2년이 지난 지금 시점에서 나는 객체지향을 어느정도 맛보았고 무엇이 객체지향인지 알고 있다는 생각을 했지만, 내 손등을 때리는 것과 같았다.

 

우선 객체는 클래스가 아니라 책임과 역할, 협력이라는 것 부터서 시작되었다.

 

나는 지금까지 클래스 지향 프로그래밍을 하고 있었던 것이었고, 객체 지향을 하는 것이 아니었다는 생각이 들었다.

 

예를 들어 DB에 접근해 글을 수정하는 메서드를 작성한다고 해보자.

public void updatePosting(Long postNumber) {

  // DB 객체 생성
  DBConnection connection = new DBConnection();

  // DB 에 연결
  connection.connectToDatabase();

  // 내 게시글 가져오기
  Posting posting = connection.getPostById(postNumber);

  // 게시글 수정
  String newTitle = "수정할 글 제목";
  String newContent = "수정할 글 본문";
  posting.setTitle(newTitle);
  posting.setContent(newContent);

  // db 에 저장
  connection.save(posting);
}

 

나는 지난 2년동안 이 코드가 충분히 객체지향적인 코드인줄 알고 있었다.


왜? DBConnection 클래스, Posting 클래스를 이용하니까.

 

클래스는 곧 객체지향의 핵심이니까! 라고 잘못된 생각을 했었다.

하지만 이건 객체지향의 언어로 절차지향 프로그래밍을 하는 것과 다를 것이 없었다.

 

이유는 Posting 객체와는 아무런 협력을 하지 않고 updatePosting() 메서드 내부에서 모든 것을 수행하려 하기 때문이다.

 

즉, 나는 Posting 객체에게 자율성을 주려하지 않았고, 협력을 생각하지 않았기 때문이다.

 

딱 1장만 읽은 시점에서 내가 위의 코드를 객체지향적으로 바꾸려 한다면 사실 선택지가 많이 없다.


아는 것도 아직 많이 없지만 지금 까지의 여러 가르침을 주신 조영호님의 이야기를 되새김 해보며 다시 구성하자면 아마 이런 형태가 되지 않을까 싶다.

public void updatePosting(Long postNumber) {

  // DB 객체 생성
  DBConnection connection = new DBConnection();

  // DB 에 연결
  connection.connectToDatabase();

  // 내 게시글 가져오기
  Posting posting = connection.getPostById(postNumber);

  // 게시글 수정
  posting.updateTitleAndContent(newTitle, newContent);

  // db 에 저장
  connection.save(posting);
}

이렇게 된다면 Posting 객체를 조금 더 존중하는 것 같다.


updatePosting 메서드에서 직접 조작한다는 것은 Posting 객체의 자율성을 빼앗는 것이고, Posting 객체는 협력이 아닌 일방적인 관계의 의한 협조가 된다.

 

그래서 Posting 객체에거 title 과 content를 넘겨주고 이를 적절히 처리하라고 하는 것이다.

 

다시 한 번 되새겨보자.

객체지향은 클래스의 구조와 메서드 호출이 아닌 객체의 역할, 책입, 협력이다.

댓글