Objects Study - Chapter1. 객체, 설계

소프트웨어의 목적

Robert C. Martin은 클린 소프트웨어: 애자일 원칙과 패턴, 그리고 실천방법에서 소프트웨어 모듈이 가져야 하는 세 가지 기능에 관해 설명한다.
(모듈이란, 크기와 상관 없이 클래스나 패키지, 라이브러리와 같은 프로그램을 구성하는 임의의 요소를 의미한다.)

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

읽기 어려운 코드는 무엇일까?

하나의 Class 또는 Method에서 너무 많은 항목을 다룬다.
다시 말해 Class, Method에서 하나 이상의 책임을 가지고 동작하는 코드이기 때문에
코드를 읽는 사람이 집중해야 할 부분이 많다.

코드를 작성하는 사람뿐만 아니라 코드를 읽고 이해해야 하는 사람에게 모두 부담이 된다.

의존성(Dependency)이란?

의존성이란 하나의 객체 안에서 다른 객체에 대한 코드를 호출하는 것이다.
의존성은 변경이란 문제와 직결된다. (의존성을 갖는 코드를 변경하게 되면 호출하는 객체에도 수정이 필요하기 때문)
객체 사이의 의존성이 강한 경우를 가리켜 결합도(Coupling) 가 높다고 말한다.

좋은 소프트웨어를 설계하기 위한 목표는 결합도가 낮은 코드를 설계하는 것이다.

결합도는 낮추는 방법은 무엇인가?

객체에게 자율성을 부여하자

자율성이란 객체 내부의 데이터를 변경하는 것을 객체 스스로에게 위임하는 행위를 말한다.
객체 내의 데이터를 다른 객체가 변경하는 것을 막는 것만으로도 결합도를 낮출 수 있다.

이 처럼 객체 스스로 자기 자신의 data를 제어하는 코드를 응집도(cohesion) 가 높은 코드라고 말한다.

  • 객체의 응집도를 높이기 위해서는 객체 스스로 자신의 데이터를 책임진다.
  • 객체는 자신의 데이터를 스스로 처리하는 자율적인 존재여야 한다.

객체를 캡슐화 한다

개념적이나 물리적으로 객체 내부의 세부적인 사항을 감추는 것을 캡슐화(encapsulation) 라 한다.
캡슐화의 목적은 변경하기 쉬운 객체 를 만들기 위함이다.

  • 객체 내부의 접근을 제한한다.
  • 다른 객체에서 객체 내부의 데이터를 접근하거나 수정하지 못하도록 막으면,
    객체 내에서 일어하는 일만 수정하면 되기 때문에 하나의 Class 파일만 변경할 수 있어 변경에 용이하다.

의존관계는 Interface에만 의존한다

객체를 Interface와 구현부로 나누고 Interface만 공개한다.
객체간의 의존성이 필요한 부분은 Interface에서 제공하는 메서드를 가지고 코드를 작성하고 실제 구현부는
각각의 객체에 위임한다.

절차 지향 vs 객체 지향

절차 지향 프로그래밍(Procedural Programming)이란, Process (객체의 행위)와 데이터가 별도의 모듈에 위치한다.
객체 내의 데이터를 변경하는 주체가 모듈 내에서 변경하는 것이 아닌 다른 모듈에서 변경 시킨다.

객체 지향 프로그래밍 (Object Oriented Programming)이란, Process(객체의 행위)와 데이터가 같은 모듈 내에 위치 한다.

요약

  • 변경하기 쉬운 설계는 한번에 하나만을 변경 할 수 있는 설계이다.
    • 설계를 어렵게 만드는 것은 의존성이다.
    • 하나의 변경으로 인해 의존성을 갖는 여러 코드를 변경하는 것은 좋지 못하다.
  • 훌륭한 객체 지향 설계는 캡슐화를 이용해 의존성을 적절히 관리하여 의존성을 최대한 낮추는 것이다.
    • 객체 외부의 파급력이 없어서 변경이 수월하다.
    • 캡슐화를 하면 객체의 자율성↑, 응집도↑, 결합도↓
  • 객체는 생물 처럼 스스로 생각하고 행동하도록 의인화하며 설계하면 도움이 된다.
    • 객체에 대한 적절한 책임을 위임한다.
    • 기능은 최대한 객체에 위임한다.
  • 좋은 설계란, 오늘 요구하는 기능을 온전히 수행하면서 내일의 변경을 매끄럽게 수용 할 수 있어야 한다.
    • 개발을 시작하는 시점에 요구사항 분석이 100% 이루어지는 것은 불가능에 가깝다.
    • 코드는 변화하고 살아 숨쉰다. 변화에 유연하게 대처할 수 있는 코드를 작성할 수 있는 설계를 해야 한다.

참고

  • Objects(코드로 이해하는 객체지향 설계) - 객체, 설계