[개발 도서 리뷰] 객체지향의 사실과 오해

·2023년 1월 15일
0

개발 도서 리뷰

목록 보기
4/5
post-thumbnail

객체 지향에 대해 추상적인 내용이 주를 이루어서 좀 어려웠다. 제대로 이해한 건지는 모르겠지만 내 나름대로 중요하다고 생각하는 점을 정리해 보려고 한다. 쓰다 보니 길어져서 아무래도 나만 읽을 것 같긴 하지만 ㅋㅋ 중요한 점이랑 몰랐던 점이 한 둘이 아니라 어쩔 수 없었다. 다음에 기회가 된다면 이걸 더 쉽게 정리해 봐야겠다.

1. 객체지향의 목표는 실세계를 모방하는 것이 아니다.

  • 실세계에 대한 비유가 객체지향의 개념을 이해하는 데는 유용하지만, 실무적인 관점에서는 부적합하다.

  • 객체지향의 목표는 현실 세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조하는 것이다.

  • 소프트웨어 상품은 실제 세계의 상품이 하지 못하는 가격 계산과 같은 행동을 스스로 수행할 수 있다.

  • 현실 세계와 객체지향 사이의 관계를 좀 더 정확하게 설명할 수 있는 단어는 은유이다.

  • 은유 관계에 있는 실제 객체의 이름으로 사용하면 표현적 차이를 줄여 소프트웨어의 구조를 쉽게 예측할 수 있다. 따라서 소프트웨어 객체에 대한 현실 객체의 은유를 효과적으로 사용할 경우 표현적 차이를 줄일 수 있으며, 이해하기 쉽고 유지보수가 용이한 소프트웨어를 만들 수 있다.

2. 객체는 자율적이고, 협력적이다.

  • 객체는 인간의 사회와 유사하게, 공동의 목표를 달성하기 위해 협력에 참여하지만 스스로의 결정과 판단에 따라 행동하는 존재이다.

  • 객체의 자율성은 내부와 외부를 명확하게 구분하는 것으로부터 나온다. 객체는 다른 객체가 무엇을 수행하는지는 알 수 있지만 어떻게 수행하는지에 대해서는 알 수 없다.

  • 객체는 시스템의 행위를 구현하기 위해 다른 객체와 협력한다. 각 객체는 협력 내에서 정해진 역할을 수행하며 역할은 관련된 책임의 집합이다.

  • 객체는 다른 객체와 협력하기 위해 메시지를 전송하고, 메시지를 수신한 객체는 메시지를 처리하는 데 적합한 메서드를 자율적으로 선택한다. 메시지와 메서드를 분리하는 것은 객체의 자율성을 높이는 핵심 메커니즘이다. 이것은 캡슐화라는 개념과도 관련되어 있다.

  • 전통적인 개발 방법은 데이터와 프로세스를 엄격하게 구분한다. 이에 반해 객체지향에서는 데이터와 프로세스를 객체라는 하나의 틀 안에 함께 묶어 놓음으로써 객체의 자율성을 보장한다.

3. 객체의 상태와 행동, 식별자

  • 객체는 상태와 행동, 식별자를 가지고 있다.

상태

  • 객체는 상태를 가지며 상태는 변경 가능하다.

  • 객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티라고 한다. 일반적으로 변경되지 않고 고정되기 때문에 '정적'이다.

  • 프로퍼티 값은 시간이 흐름에 따라 변경되기 때문에 '동적'이다.

  • 객체의 프로퍼티는 단순한 값인 속성과 다른 객체를 가리키는 링크라는 두 가지 종류의 조합으로 표현할 수 있다.

행동

  • 객체의 상태를 변경시키는 것은 객체의 행동이다.
    • 행동의 결과는 상태에 의존적이며 상태를 이용해 서술할 수 있다.
    • 행동의 순서가 실행 결과에 영향을 미친다.

식별자

  • 객체는 어떤 상태에 있더라도 유일하게 식별 가능하다. 객체가 아닌 단순한 값은 식별자를 가지지 않는다.

4. 캡슐화

  • 객체는 상태를 캡슐 안에 감춰둔 채 외부로 노출하지 않는다. 객체가 외부에 노출하는 것은 행동뿐이며, 외부에서 객체에 접근할 수 있는 유일한 방법 또한 행동뿐이다.

  • 객체를 캡슐화하는 것은 결과적으로 객체의 자율성을 높인다. 협력에 참여하는 객체들의 지능이 높아질수록 협력은 유연하고 간결해진다.

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

  • 상태를 먼저 결정하고 행동을 나중에 결정하는 방법은 설계에 나쁜 영향을 끼친다.

  • 상태를 먼저 고려하는 방식은 협력을 고려하지 않고 객체를 따로 설계하게 만들어 협력에 적합하지 못한 객체를 만들어 낸다. 따라서 재사용성 또한 저해된다.

6. 타입과 추상화

  • 추상화를 함으로써 복잡한 세상을 제어 가능할 정도로 단순하게 만든다.

  • 객체지향 프로그램을 작성할 때 우리는 객체를 일종의 데이터처럼 사용한다. 따라서 객체를 타입에 따라 분류하고 그 타입에 이름을 붙이는 것은 결국 프로그램에서 이용할 새로운 데이터 타입을 선언하는 것과 같다.

  • 객체의 타입을 결정하는 것은 객체의 행동뿐이다. 객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는 데 아무런 영향도 미치지 않는다.

  • 같은 타입에 속한 객체는 행동만 동일하다면 서로 다른 데이터를 가질 수 있다. 여기서 동일한 행동이란 동일한 책임을 의미하며, 동일한 책임이란 동일한 메시지 수신을 의미한다. 따라서 동일한 타입에 속한 객체는 내부의 데이터 표현 방식이 다르더라도 동일한 메시지를 수신하고 이를 처리할 수 있다. 다만 내부의 표현 방식이 다르기 때문에 동일한 메시지를 처리하는 방식은 서로 다를 수 밖에 없다. 이것은 다형성에 의미를 부여한다.

  • 타입은 시간에 따라 동적으로 변하는 앨리스의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해준다. 이런 관점에서 타입은 추상화다.

  • 객체를 분류하기 위해 타입을 결정한 후 프로그래밍 언어를 이용해 타입을 구현할 수 있는 한 가지 방법이 클래스이다.

7. 역할, 책임, 협력

협력

  • 협력은 다수의 요청과 응답으로 구성되며 저체적으로 협력은 다수의 연쇄적인 요청과 응답의 흐름으로 구성된다.

책임

  • 객체지향 개발에서 가장 중요한 능력은 책임을 능숙하게 할당하는 것이다. 책임이 제자리를 잡지 않은 상태에서 구현하는 것은 변경에 취약하고 다양한 협력에 참여할 수 없는 비자율적인 객체를 만들게 된다.

  • 객체의 책임은 하는 것(doing)과 아는 것(knowing)의 두 가지 범주로 나눌 수 있다.

  • 메시지를 기반으로 객체가 책임을 수행하게 하는 것이 가능하다. 하지만 책임과 메시지의 수준이 같지는 않다. 책임을 결정한 후 협력을 정제하면서 이를 메시지로 변환할 때는 하나의 책임이 여러 메시지로 분할되는 것이 일반적이다.

  • 객체지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다.

  • 책임은 자율적이어야 한다. 자율적인 책임의 특징은 객체가 어떻게 해야 하는 것인가가 아니라 무엇을 해야 하는가를 설명한다.

  • 책임은 너무 추상적이여도 안된다.

역할

  • 역할은 협력 내에서 다른 객체로 대체할 수 있음을 나타내는 일종의 표식이다.

  • 어떤 객체라도 역할을 대신 할 수는 없다. 역할을 대체하기 위해서는 각 역할이 수신할 수 있는 메시지를 동일한 방식으로 이해해야 한다.

  • 역할의 개념을 사용하면 유사한 협력을 추상화해서 인지 과부하를 줄일 수 있다. 역할은 객체지향 설계의 단순성, 유연성, 재사용성을 뒷받침하는 핵심 개념이다.

  • 역할의 가장 큰 가치는 하나의 협력 안에 여러 종류의 객체가 참여할 수 있게 함으로써 협력을 추상화할 수 있다는 것이다. 따라서 역할을 이용하면 협력을 추상화함으로써 단순화할 수 있다.

  • 역할의 대체 가능성은 행위 호환성을 의미하고, 행위 호환성은 동일한 책임의 수행을 의미한다.

흔한 오류

  • 객체가 존재하는 이유는 행위를 수행하며 협력에 참여하기 위해서다.

  • 객체지향의 핵심은 클래스를 어떻게 구현할 것인가가 아니라 객체가 협력 안에서 어떤 책임과 역할을 수행할 것인지를 결정하는 것이다.

  • 객체지향 입문자들이 데이터나 클래스를 중심으로 애플리케이션을 설계하는 이유는 협력이라는 문맥을 고려하지 않고 각 개체를 독립적으로 바라보기 때문이다.

  • 어떤 애플리케이션에 적합한 객체를 설계하기 위해서는 협력이라는 문맥에서 바라 보아야 한다.

객체 지향 설계 기법

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

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

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

  • 테스트 주도 개발 : 테스트가 아니라 설계를 위한 기법. 실제 목적은 구체적인 코드를 작성해나가면서 역할, 책임, 협력을 식별하고 식별된 역할 책임, 협력이 적합한지를 피드백받는 것이다.

8. 메시지

  • 메시지가 있다면 메시지 그 자체와 그 메시지를 처리할 수 있는 방법이 필요하게 된다. 그 방법이 바로 메서드이다. 메서드는 클래스 안에 포함된 함수 혹은 프로시저를 통해 구현된다.

  • 메시지와 메서드를 활용하면 다형성이라는 개념을 이해할 수 있다. 메시지는 무엇이 실행될지는 명시하지만 메시지를 어떻게 실행할 것인지는 수신자가 전적으로 결정할 수 있다. 메시지 처리 방법에는 어떤 제약도 없기 때문에 동일한 메시지라고 하더라도 서로 다른 방식의 메서드를 이용하여 처리할 수 있다. 따라서 다형성을 하나의 메시지와 하나 이상의 메서드 사이의 관계로 볼 수 있다.

9. 책임 주도 설계

  • What/Who 사이클 : 책임-주도 설계의 핵심은 어떤 행위가 필요한지를 먼저 결정한 후에 이 행위를 수행할 객체를 결정하는 것이다.

  • 묻지 말고 시켜라 : 송신자는 수신자가 어떤 객체인지 모르기 때문에 객체에 관해 꼬치꼬치 캐물을 수 없다. 단지 송신자는 수신자가 어떤 객체인지는 모르지만 자신이 전송한 메시지를 잘 처리할 것이라는 것을 믿고 메시지를 전송할 수 밖에 없다.

10. 인터페이스

  • 인터페이스는 객체가 책임을 수행하기 위해 외부로부터 메시지를 받기 위한 통로이다.

  • 객체가 어떤 메시지를 수신할 수 있느냐가 어떤 책임을 수행할 수 있느냐와 어떤 인터페이스를 가질 것인지를 결정한다.

멧 와이스펠드는 객체지향적인 사고 방식을 이해하기 위해서는 다음의 세 가지 원칙이 중요하다고 주장한다.

  • 좀 더 추상적인 인터페이스

  • 최소 인터페이스 : 외부에서 사용할 필요가 없는 인터페이스는 최대한 노출하지 말라

  • 인터페이스와 구현 간에 차이가 있다는 점을 인식

    • 객체를 구성하지만 공용 인터페이스에 포함되지 않는 모든 것이 구현이다.

    • 객체는 상태를 가진다. 상태는 객체에 포함되겠지만 객체 외부에 노출되는 공용 인터페이스의 일부는 아니다. 따라서 상태를 어떻게 표현할 것인가는 객체의 구현에 해당한다.

    • 객체는 행동을 가진다. 행동은 메시지를 수신했을 때만 실행되는 일종의 메시지 처리 방법이다. 이 처리 방법을 메서드라고 한다. 메서드를 구성하는 코드 자체는 객체 외부에 노출되는 공용 인터페이스의 일부는 아니기 때문에 객체의 구현 부분에 포함된다.

    • 객체의 외부와 내부를 분리하라는 말은 결국 객체의 공용 인터페이스와 구현을 명확하게 분리하라는 말과 동일하다.

    • 훌륭한 객체란 구현을 모른 채 인터페이스만 알면 쉽게 상호작용할 수 있는 객체를 의미한다. 이것은 객체를 설계할 때 객체 외부에 노출되는 인터페이스와 객체의 내부에 숨겨지는 구현을 명확하게 분리해서 고려해야 한다는 것을 의미한다. 이를 인터페이스와 구현의 분리 원칙이라고 한다.

11. 책임의 자율성이 협력의 품질을 결정한다.

  • 자율적인 책임은 협력을 단순하게 만든다.

    • 자율적인 책임은 세부적인 사항들을 무시하고 의도를 드러내는 하나의 문장으로 표현함으로써 협력을 단순하게 만든다. 즉, 책임이 적절하게 추상화된다.
  • 자율적인 책임은 객체의 외부와 내부를 명확하게 분리한다.

    • 요청하는 객체가 몰라도 되는 사적인 부분이 객체 내부로 캡슐화되기 때문에 인터페이스와 구현이 분리된다.
  • 책임이 자율적일 경우 책임을 수행하는 내부적인 방법을 변경하더라도 외부에 영향을 미치지 않는다.

    • 변경의 파급효과가 객체 내부로 캡슐화되기 때문에 두 객체 간의 결합도가 낮아진다.
  • 자율적인 책임은 협력의 대상을 다양하게 선택할 수 있는 유연성을 제공한다.

  • 객체가 수행하는 책임들이 자율적일수록 객체의 역할을 이해하기 쉬워진다.

    • 객체가 수행하는 책임들이 자율적일수록 객체의 존재 이유를 명확하게 표현할 수 있다. 객체는 동일한 목적을 달성하는 강하게 연관된 책임으로 구성되기 때문이다. 책임이 자율적일수록 객체의 응집도를 높은 상태로 유지하기가 쉬워진다.

요약

  • 책임이 자율적일수록 적절하게 축상화되며, 응집도가 높아지고, 결합도가 낮아지며, 캡슐화가 증진되고, 인터페이스와 구현이 명확히 분리되며, 설계의 유연성과 재사용성이 향상된다.

12. 기능 설계 vs 구조 설계

  • 길을 모른다고 가정했을 때, 사람들에게 길을 물어 찾아가는 방법은 기능적이고 해결 방법 지향적인 접근법이라면 지도를 이용하는 방법은 구조적이고 문제 지향적인 접근법이다.

  • 사람들의 요구사항은 계속 변하기 때문에 모델이 제공해야 하는 기능 역시 이에 따라 변하게 된다. 따라서 기능을 중심으로 구조를 종속시키는 접근법은 범용적이지 않고 재사용이 불가능하며 변경에 취약한 모델을 낳게 된다.

  • 이와 달리 안정적인 구조를 중심으로 기능을 종속시키는 접근법은 범용적이고 재사용 가능하며 변경에 유연하게 대처할 수 있는 모델을 만든다.

  • 전통적인 소프트웨어 개발 방법은 변경이 빈번하게 발생하는 기능에 안정적인 구조를 종속시키는 길을 묻는 방법과 유사하다. 반면에 객체지향 개발 방법은 안정적인 구조에 변경이 빈번하게 발생하는 기능을 종속시키는 지도의 방법이다. 즉, 객체지향은 자주 변경되는 기능이 아니라 안정적인 구조를 기반으로 시스템을 구조화한다.

기능과 구조

  • 구조는 사용자나 이해관계자들이 도메인에 관해 생각하는 개념과 개념들 간의 관계로 표현한다.

  • 기능은 사용자의 목표를 만족시키기 위해 책임을 수행하는 시스템의 행위로 표현한다.

  • 일반적으로 기능을 수집하고 표현하기 위한 기법을 유스케이스 모델링이라고 하고 구조를 수집하고 표현하기 위한 기법을 도메인 모델링 이라고 한다. 두 가지 모델링 활동의 결과물을 각각 유스케이스와 도메인 모델이라고 한다.

13. 도메인 모델

  • 소프트웨어를 사용하는 사람들은 자신이 관심을 가지고 있는 특정한 분야의 문제를 해결하기 위해 소프트웨어를 사용한다. 이처럼 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고 한다.

  • 도메인 모델이란 사용자가 프로그램을 사용하는 대상 영역에 대한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다. 도메인 모델은 소프트웨어 개발과 관련된 이해관계자들이 도메인에 대해 생각하는 관점이다.

  • 은행 업무에 종사하는 살마들은 은행 도메인을 고객과 계좌 사이의 돈의 흐름으로 이해할 것이다. 게임 플레이어들은 게임 도메인을 캐릭터와 몬스터 그리고 몬스터가 떨구는 아이템 관의 관계로 파악한다. 소프트웨어의 도메인이 무엇이든 상관없이 그곳에는 항상 도메인과 관련된 사람들이 도메인을 바라보는 모델이 존재한다.

  • 도메인 모델은 이해관계자들이 바라보는 멘탈 모델이다. 멘탈 모델이란 사람들이 자기 자신, 다른 사람, 환경, 자신이 상호작용하는 사물들에 대해 갖는 모형이다.

  • 도널드 노먼은 제품을 설계할 때 제품에 관한 모든 것이 사용자들이 제품에 대해 가지고 있는 멘탈 모델과 정확하게 일치해야 한다고 주장한다. 사용자들은 자신의 멘탈 모델과 유사한 방식으로 제품이 반응하고 움직일 것이라고 기대하기 때문에 훌륭한 디자인이란 사용자가 예상하는 방식에 따라 정확하게 반응하는 제품을 만드는 것이다.

  • 노먼은 멘탈 모델을 사용자 모델, 디자인 모델, 시스템 이미지의 세 가지로 구분한다. 사용자 모델은 사용자가 제품에 대해 가지고 있는 개념들의 모습이다. 디자인 모델은 설계자가 마음 속에 갖고 있는 시스템에 대한 개념화다. 시스템 이미지는 최종 제품이다.

  • 사용자의 모델과 디자인 모델이 동일하다면 이상적이겠지만 사용자와 설계자는 직접적으로 상호작용할 수 없으며 단지 최종 제품인 시스템 그 자체를 통해서만 의사소통할 수 있다. 따라서 설계자는 디자인 모델을 기반으로 만든 시스템 이미지가 사용자 모델을 정확하게 반영하도록 노력해야 한다.

  • 도메인 모델은 도메인에 대한 사용자 모델, 디자인 모델, 시스템 이미지를 포괄하도록 추상화한 소프트웨어 모델이다. 따라서 도메인 모델은 소프트웨어에 대한 멘탈 모델이다.

  • 객체지향을 사용하면 사용자들이 이해하고 있는 도메인의 구조와 최대한 유사하게 코드를 구조화할 수 있다. 동적인 객체가 가진 복잡성을 극복하기 위해 정적인 타입을 이용해 세상을 단순화할 수 있으며, 클래스라는 도구를 이용해 타입을 코드 안으로 옴길 수 있다.

표현적 차이

  • 소프트웨어 객체와 현실 객체 사이의 의미적 거리를 가리켜 표현적 차이 또는 의미적 차이라고 한다. 핵심은 은유를 통해 현식 객체와 소프트웨어 객체 사이의 차이를 최대한 줄이는 것이다.

  • 은유를 통해 투영해야 하는 대상은, 사용자가 도메인에 대해 생각하는 개념들이다. 즉, 소프트웨어 객체를 창조하기 위해 우리가 은유해야 하는 대상은 도메인 모델이다.

  • 표현적 차이가 중요한 이유는 소프트에어를 이해하고 쉽게 만들어주기 때문에 코드의 구조가 도메인의 구조를 반영하기 때문에 도메인을 이해하면 코드를 이해하면 코드를 이해하기가 훨씬 수월해진다.

  • 도메인 모델을 기반으로 코드를 작성하는 이유는 도메인 모델이 제공하는 구조가 상대적으로 안정적이기 때문이다. 사용자 모델에 포함된 개념과 규칙은 비교적 변경될 확률이 적기 때문에 사용자 모델을 기반으로 설계와 코드를 만들면 변경에 쉽게 대처할 수 있는 가능성이 커진다.

14. 유스케이스

  • 사용자의 목표를 달성하기 위해 사용자와 시스템 간에 이뤄지는 상호작용의 흐름을 텍스트로 정리한 것을 유스케이스라고 한다.

  • 유스케이스의 가치는 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항들을 이야기 형식으로 묶릉 수 있다는 점이다. 산발적으로 흩어져 있는 기능에 사용자 목표라는 문맥을 제공함으로써 각 기능이 유기적인 관계를 지닌 체계를 이룰 수 있게 한다.

  • 유스케이스는 사용자와 시스템 간의 상호작용을 보여주는 텍스트다. 유스케이스는 다이어그램이 아니다. 중요한 것은 유스케이스 안에 포함돼 있는 상호작용의 흐름이다.

  • 유스케이스는 하난의 시나리오가 아닌 여러 시나리오들의 집합이다. 시나리오들을 유스케이스 인스턴스라고도 한다.

  • 유스케이스는 단순한 피처(feature)목록과 다르다. 피처는 시스템이 수행해야 하는 기능의 목록을 단순하게 나열한 것이다. 피처의 단점은 두 피처를 연관이 없는 독립적인 기능으로 보이게끔 만든다는 점이다. 유스케이스는 단순히 기능을 나열하는 것이 아니라 이야기를 통해 연관된 기능들을 함께 묶을 수 있다는 점이다.

  • 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하지 말아야 한다.

  • 유스케이스는 내부 설계와 관련된 정보를 포함하지 않는다. 유스케이스는 시스템의 내부 구조나 실행 매커니즘에 관한 어떤 정보도 제공하지 않는다. 유스케이스에는 단지 사용자가 시스템을 통해 무엇을 얻을 수 있고 어떻게 상호작용할 수 있느냐에 관한 정보만 기술된다.

  • 유스케이스는 객체의 구조나 책임에 대한 어떤 정보도 제공하지 않는다. 유스케이스 안에 도메인 모델을 구축할 수 있는 모든 정보가 포함돼 있다는 착각에 빠지지 말아야 한다.

15. 기능과 구조의 통합

  • 변경에 유연한 소프트웨어를 만들기 위해서는 유스케이스에 정리된 시스템의 기능을 도메인 모델을 기반으로 한 객체들의 책임으로 분배해야 한다.

  • 협력의 출발은 시스템의 기능을 시스템의 책임으로 바꾸는 것이다.

  • 시스템에 할당된 커다란 책임은 시스템 안의 작은 규모의 객체들이 수행해야 하는 더 작은 규모의 책임으로 세분화된다.

  • 객체를 선택할 때 도메인 모델이 등장한다. 우리는 도메인 모델에 포함된 개념을 은유하는 소프트웨어 객체를 선택해야 한다. 이것은 소프트웨어와 코드 사이의 표현적 차이를 줄이는 첫걸음이다.

  • 협력을 완성하는 데 필요한 메시지를 식별하면서 객체들에게 책임을 할당해 나간다.

  • 마지막으로 협력에 참여하는 객체를 구현하기 위해 클래스를 추가하고 속성과 함께 메서드를 구현하면 시스템의 기능이 완성된다. 이제 코드는 불안정한 기능을 수용할 수 있는 안정적인 구조에 기반한다.

  • 안정적인 도메인 모델을 기반으로 시스템의 기능을 구현하고, 도메인 모델과 코드를 밀접하게 연관시키기 위해 노력하는 것이 유지보수하기 십고 유연한 객체지향 시스템을 만드는 방법이다.

16. 객체 지향 설계 안의 세 가지 관점

  • 개념 관점에서 설계는 도메인 안에 존재하는 개념과 개념들 사이의 관계를 표현한다. 이 관점은 사용자가 도메인을 바라보는 관점을 반영한다. 따라서 실제 도메인의 규칙과 제약을 최대한 유사하게 반영하는 것이 핵심이다.

  • 커피를 제조하는 과정을 변경해야 한다면 소프트웨어 안에서도 Barista라는 클래스가 커페를 제조할 것이라고 쉽게 유추할 수 있다. 소프트웨어 클래스와 도메인 클래스 사이의 간격이 좁으면 좁을수록 기능을 변경하기 위해 뒤적거려야 하는 코드의 양도 점점 줄어든다.

  • 명세 관점은 도메인의 개념이 아니라 실제로 소프트에어 안에서 살아 숨쉬는 객체들의 책임에 초점을 맞추게 된다. 즉, 객체의 인터페이스를 바라보게 된다. 명세 관점에서 프로그래머는 객체가 협력을 위해 무엇을 할 수 있는가에 초점을 맞춘다.

  • 최대한 변화에 안정적인 인터페이스를 만들기 위해서는 인터페이스를 통해 구현과 관련된 세부 사항이 드러나지 않게 해야 한다.

  • 구현 관점의 초점은 객체들이 책임을 수행하느 데 필요한 동작하는 코드를 작성하는 것이다. 따라서 프로그래머는 객체의 책임을 어떻게 수행할 것인가에 초점을 맞추며 인터페이스를 구현하는데 필요한 속성과 메서드를 클래스에 추가한다.

  • 클래스의 메서드와 속성은 구현에 속하며 공용 인터페이스의 일부가 아니다. 따라서 메서드와 속성이 철저하게 클래스 내부로 캡슐화돼야 한다는 것을 의미한다.

  • 다른 사람들이 여러분의 코드를 읽으면서 세 가지 관점을 쉽게 포착하지 못한다면 세 가지 관점이 명확하게 드러날 수 있게 코드를 개선하라. 그것이 변경에 유연하게 대응할 수 있는 객체지향 코드를 작성하는 가장 빠른 길이다.


이 글을 읽는 사람이 있기나 할까? 최대한 줄이고 줄였는데도 이 정도다. 하여튼 나는 정리하면서 다시 책을 꼼꼼히 읽었기 때문에 이제야 머리에 정리가 되는 기분이다.

profile
전 이것도 몰라요

0개의 댓글