[오브젝트] 1장 : 객체, 설계

Young-Jun Kim·2022년 10월 30일
0

오브젝트

목록 보기
2/3

책의 이야기

무엇이 문제인가

1장에서는 객체를 어떻게 설계해야 하는지를 말하고 있다. 로버트 마틴 (Robert C. Martin)은 <클린 소프트웨어: 애자일 원칙과 패턴, 그리고 실천 방법> 에서 소프트웨어 모듈이 가져야 하는 세 가지 기능에 관해 설명했다.

  1. 실행 중에 제대로 동작하는 것
    • 모듈의 존재 이유이다.
  2. 변경을 위해 존재하는 것
    • 대부분의 모듈은 생명주기 동안 변경되기 때문에, 간단한 작업만으로 변경이 가능해야 한다.
  3. 코드를 읽는 사람과 의사소통하는 것
    • 모듈은 특별한 훈련 없이도 개발자가 쉽게 읽고 이해할 수 있어야 한다.

‘모듈은 위 세 가지 기능 중 한가지 라도 문제가 있다면 개선되어야 한다.’ 라고 하였다. 로버트 마틴의 말을 바탕으로 어떤 코드가 좋지 못한 코드인지, 좋은 코드가 되기 위해서 어떻게 되어야 하는지 책의 흐름대로 짚어보자.

예상을 빗나가는 코드

  • 이해 가능한 코드란 그 동작이 우리의 예상에서 크게 벗어나지 않는 코드이다.
    • 코드가 우리의 상식과 다르게 동작하면 코드를 읽는 사람과 제대로 의사소통하기 힘들다.
  • 코드를 이해하기 어렵게 만드는 또 다른 요소는 코드를 이해하기 위해 여러 가지 세부적인 내용을 알아야하는 것이다.

변경에 취약한 코드

  • 코드의 변경은 객체 사이의 의존성과 관련된 문제이다.
    • 의존성이라는 말 속에는 어떤 객체가 변경될 때 그 객체에게 의존하는 다른 객체도 함께 변경될 수 있다는 사실이 내포돼 있다.
  • 하지만 객체 사이의 의존성을 완전히 없애는 것이 정답은 아니다.
    • 객체지향 설계는 서로 의존하면서 협력하는 객체들의 공동체를 구축하는 것이다.
    • 애플리케이션의 기능을 구현하는 데 필요한 최소의 의존성만 유지하고 불필요한 의존성을 제거해야 한다.
  • 객체 사이의 의존성이 과한 경우를 결합도가 높다고 말한다.
    • 두 객체 사이의 결합도가 높으면 높을수록 변경될 확률도 높아지기 때문에 변경하기 어려워진다.
💡 설계의 목표는 객체 사이의 결합도를 낮춰 변경이 용이한 설계를 만드는 것이어야 한다.

설계 개선하기

자율성을 높이자

  • 설계를 변경하지 어려운 이유는 어떠한 객체가 여러 객체에 마음대로 접근할 수 있기 때문이다.
    • 각각을 자율적인 존재가 되도록 설계해야 한다.
  • 객체의 가시성을 조절하여 외부에서 필드나 메서드에 직접 접근하지 못하게 해야한다.
    • 개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것을 캡슐화라고 부른다.
    • 캡슐화를 통해 객체 내부로의 접근을 제한하면 객체 사이의 결합도를 낮출 수 있다.
  • 객체를 인터페이스와 구현으로 나누고 인터페이스만 공개하는 것은 객체 사이의 결합도를 낮추고 변경하기 쉬운 코드를 작성하게 해준다.

무엇이 개선됐는가

  • 인터페이스를 의존하기 때문에 내부의 구현을 변경하더라도 외부에서는 변경이 필요하지 않다.

어떻게 한 것인가

  • 외부에서 제어하는 것이 아닌 객체가 동작을 직접 수행하면 객체의 자율성이 높아지고, 이해도 쉬우며 유연한 설계를 얻을 수 있다.

캡슐화와 응집도

  • 객체 내부의 상태를 캡슐화하고 객체 간에 오직 메시지를 통해서만 상호작용하도록 해야 한다.
  • 객체의 응집도를 높이기 위해 객체 스스로 자신의 데이터를 책임저야 한다.
    • 연관성 없는 작업은 다른 객체에게 위임하는 객체를 응집도가 높다고 말한다.
  • 외부의 간섭을 최대한 배제하고 메시지를 통해서만 협력하는 자율적인 객체들의 공동체를 만들어야 한다.

절차지향과 객체지향

  • 프로세스와 데이터를 별도의 모듈에 위치시키는 방식을 절차적 프로그래밍이라고 부른다.
    • 모든 처리가 하나의 클래스에서 이루어지고 나머지 클래스는 데이터의 역할만 수행한다.
    • 절차적 프로그래밍은 우리의 직관에 위배된다.
    • 절차적 프로그래밍의 세상에서는 데이터의 변경으로 인한 영향을 지역적으로 고립시키기 어렵다.
  • 데이터와 프로세스가 동일한 모듈 내부에 위치기키는 방식을 객체 지향 프로그래밍이라고 부른다.
    • 캡슐화를 이용해서 의존성을 적절히 관리함으로써 객체 사이의 결합도를 낮추는 것이다.

책임의 이동

  • 두 방식 사이에 근본적인 차이를 만드는 것은 책임의 이동이다.
    • 객체가 어떤 데이터를 가지느냐보다는 객체에 어떤 책임을 할당할 것인에 초점을 맞춰야 한다.

그래, 거짓말이다!

  • 현실에서는 수동적인 존재하고 하더라도 일단 객체지향의 세계에 들어오면 모든것이 능동적이고 자율적인 존재로 바뀐다.
    • 이러한 원칙을 의인화라고 부른다.

객체지향 설계

설계가 왜 필요한가?

  • 설게는 코드 작성의 일부이며 코드를 작성하지 않고서는 검증할 수 없다.
  • 우리는 오늘 완성해야 하는 기능을 구현하는 코드를 작성하는 동시에 내일 쉽게 변경할 수 있는 코드를 짜야한다.
    • 좋은 설계란 오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용할 수 있는 설계이다.
  • 변경을 수용할 수 있는 설계가 중요한 이유는 요구사항이 항상 변경되고, 버그가 추가될 가능성이 높기 때문이다.

객체지향 설계

  • 변경에 유연하게 대응할 수 있는 코드를 작성해야한다.
    • 객체지향 프로그래밍은 의존성을 효율적으로 통제할 수 있는 다양한 방법을 제공함으로써 요구사항 변경에 좀 더 수월하게 대응할 수 있는 가능성을 높여준다.
  • 변경 가능한 코드란 이해하기 쉬운 코드다.
  • 객체지향 패러다임은 세상을 바라보는 방식대로 코드를 작성할 수 있게 돕는다.
  • 휼륭한 객체지향 설계란 협력하는 객체 사이의 의존성을 적절하게 관리하는 설계다.
    • 객체간 의존성을 애플리케이션을 수정하기 어렵게 만드는 주범이다.

개발자의 이야기

개발자들의 이야기를 들어보니, 객체 지향을 실무에서 적용해 보기위해 많은 분들이 시도를 했었던 것 같다. 나도 마찬가지로 인턴 일을 할 당시 객체지향을 적용하기 위해 노력해 보았지만, 다른 분들과 마찬가지로 많은 기획 수정, 짧은 개발 기간 등 여러 이유로 설계가 무너진 케이스이다. 특히 충분히 잘 설계되지 않은 객체지향은 오히려 리팩토링에 있어서 혼란을 가중시켰다. 설계란 엔지니어링의 영역이기 때문에 과도와 결핍 사이의 적절한 선을 지키기 위해서는 시니어급의 경험이 아닌 이상 어려운 부분인것 같다. 하지만 그렇다고 포기해서는 안되고 계속 도전하고 새로운 시도를 해보아야 함은 확실하다.

profile
엉뚱한 구석이 있습니다.

0개의 댓글