ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 객체지향의 사실과 오해
    BackEnd/자바 2021. 11. 10. 12:51

    객체 설계의 출발점은 "행동"

    행동에 따라 객체를 분류하기 위해서는 객체가 내부적으로 관리해야하는 데이터가 아니라
    외부에 제공해야 하는 행동이다.
    이를 위해서는 객체가 외부에 제공해야하는 책임을 먼저 결정하고
    그 책임을 수행하는 데 적합한 데이터를 나중에 결정한 후, 
    데이터를 책임을 수행하는 데 필요한 외부 인터페이스 뒤로 캡슐화해야한다.

    책임-주도 설계라고 부르는 객체지향 설계방법은 
    데이터를 먼저 생각하는 데이터-주도 설혜의 단점을 개선하기 위해 고안됐다.

    객체를 결정하는 것은 행동이다. 데이터는 행동을 따를뿐이다.

    일반화/특수화 관계(슈퍼타입/서브타입)를 구분짓는 것도 행동이다. 

    협력을 중심으로 객체를 바라보기

    흔한 실수는 협력이라는 문맥을 고려하지 않은 채 객체가 가져야할 상태와 행동부터 고민하기 시작한다는 것.
    중요한 것은 개별 객체가 아니라 객체들 사이에 이뤄지는 협력이다.
    객체 지향 설계의 전체적인 품질을 결정하는 것은 개별 객체의 품질이 아니라 여러 객체들이 모여 이뤄내는 협력의 품질이다. 

    협력이 자리 잡으면 저절로 객체의 행동이 드러나고 뒤이어 적절한 객체의 상태가 결정된다.
    어떤 협력에 참여하는지가 객체에 필요한 행동을 결정하고, 필요한 행동이 객체의 상태를 결정한다.

    책임을 어떻게 구현할지는 객체와 책임이 자리를 잡은 후 해도 늦지 않다.

    책임과 인터페이스

    객체의 책임을 이야기할 때는 일반적으로 외부에서 접근가능한 공용 서비스의 관점에서 이야기한다.
    즉, 책임은 객체의 외부에 제공해 줄 수 있는 정보와 제공해 줄 수 있는 서비스의 목록이다.
    따라서 책임은 객체의 공용 인터페이스를 구성한다.

    객체지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행하고, 어떤 메세지를 수신할 것인지 결정하는 것으로부터 시작된다. 클래스나 메서드 결정은 나중에 해도 늦지않다.

     

    데이터는 객체가 행위를 수행하는데 필요한 재료일 뿐이다.
    클래스는 단지 시스템에 필요한 객체를 표현하고 생성하기 위해 프로그래밍 언어가 제공하는 구현 매커니즘이다.


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

    • 책임 = 객체의 행동
    • 데이터 = 행동을 수행하기 위한 재료
    • 클래스 = 객체를 표현하기 위한 구현 메커니즘

    자율적인 객체와 설계의 유연함

    객체를 설계하기 위해서는 깔끔한 협력을 설계해야한다.
    협력을 설계한다는 것은 객체들끼리 주고받을 요청과 응답의 흐름을 결정한다는 것이다.
    이렇게 결정된 요청과 응답의 흐름은 객체가 협력에 참여하기 위해 수행할 책임이 된다.
    객체에게 책임을 할당하고 나면 책임은 객체가 외부에 제공하게 될 행동이 된다.
    행동이 결정되면 그 후 행동을 수행하는데 필요한 클래스와 데이터를 고민한다.

    적절한 책임이 자율적인 객체를 낳고, 자율적인 객체들이 모여 유연하고 단순한 협력을 낳는다.
    따라서 협력에 참여하는 객체가 얼마나 자율적인지가 전체 애플리케이션의 품질을 결정한다.

     

    추상화와 메시지 중심 설계

    책임은 협력에 참여하는 의도를 명확하게 설명할 수 있는 수준 안에서 추상적이어야 한다.
    어떤 책임이 자율적인지 판단하는 기준은 문맥에 따라 다르다.
    어떤 책임이 가장 적절한지는 설계 중인 협력이 무엇인가에 따라 달라진다.
    자율적인 책임의 특징은 객체가 어떻게 하는가가 아니라 무엇을 해야하는가를 설명한다는 것이다.
    객체가 유일하게 이해할 수 있는 의사소통 수단은 메세지뿐이며 객체는 메세지를 처리하기 위한 방법을 자율적으로 선택할 수 있다.
    외부의 객체는 메세지에 관해 볼 수 있지만 객체 내부는 볼 수 없기 때문에 자연스럽게 객체의 외부와 내부가 분리된다.

    메세지는 객체가 수신할 수 있는 외부의 요청을 의미하며, 
    메서드는 메세지를 처리하기 위해 선택하는 방법을 의미한다.

    다형성과 역할

    다형성이란 서로 다른 타입의 객체가 동일한 메세지에 대해 서로 다른 메서드를 이용해 메세지를 처리하는 것을 의미한다.
    다형성은 역할,책임,협력과 싶은 관련이 있다.
    서로 다른 객체들이 다형성을 만족시킨다는것은 객체들이 동일한 책임을 공유한다는 것을 의미한다.

     

    책임-주도 설계란?

    메세지 수신자들이 서로 다른 방식으로 처리를 하더라도 송신자 관점에서 이 객체들은 동일한 책임을 수행한다.
    이 메세지의 수신자들은 서로 대체 가능하다. 
    송신자가 수신자의 종류를 몰라도 메세지를 전송할 수 있다. 수신자의 종류를 캡슐화한다.

    메세지는 송,수신자 사이의 결합도를 낮춤으로 설계를 유연하고, 확장 가능하고, 재사용 가능하게 만든다.

     

    메세지가 아니라 데이터를 중심으로 객체를 내부 구조를 객체 정의의 일부로 만들기 때문에 객체의 자율성을 저해한다. (데이터 주도 설계)
    객체의 내부 구조는 감춰야 한다. 
    협력관계 속에서 무엇을 제공하고 무엇을 얻어야하는가의 관점에서 접근할 때만 훌륭한 책임을 수확할 수 있다.

    객체가 메세지를 선택하는 것이 아니라 메세지가 객체를 선택하게 한다.
    메세지가 객체를 선택하게 만들려면 메세지 중심으로 협력을 설계해야한다.

    적절한 책임을 적절한 객체에 할당하면서 메세지를 기반으로 협력하는 객체들의 관계를 발견하는 과정이다.
    이처럼 책임을 완수하기 위해 협력하는 객체들을 이용해 시스템을 설계하는 방법을 책임-주도 설계라고 한다.

    구조와 기능의 분리

    잘 변하지 않는 구조가 변경이 자주 일어나는 기능에 종속되는 것이 아니라 
    기능이 구조에 종속되도록 해야한다.
    객체지향 개발법은 이런면에서 과거의 개발방법보다 범용적이고
    재사용성이 높으며 변경에 안정적이다.
    객체 지향을 역할과 책임을 수행하며 협력하는 자율적은 객체들의 공동체로 정의했다.
    자율적인 객체들로 시스템을 분할하는 객체지향이 강력한 이유는 사람들이 
    실세계의 현상을 인지하고 이해하는 관점을 그대로 소프트웨어에 투영할 수 있기 때문이다.
    자주 변경되는 기능이 아니라 안정적인 구조를 기반으로 시스템을 분할하는 객체지향적인 접근법은 
    역할, 책임, 협력을 기반으로 시스템의 기능을 구현하는 책임-주도 설계의본질을 이해하는 데도 도움이 될 것이다.

    기능 중심 설계의 한계

    전통적인 기능분해방법은자주 변경되는 기능을 중심으로 설계하고 구조가 기능을 따르게 한다. 이는 변경에 매우 취약하다.
    기능 분해 방법의 경우 시스템 기능은 더 작은 기능으로 분해되고 각 기능은 서로 밀접하게 관련된 하나의 덩어리를 이루기 떄문에 기능이 변경될 경우 기능의 축을 따라 설계된 소프트웨어가 전체적으로 요동치게 된다.

    도메인 모델 vs 유스케이스 모델

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

    사용자가 프로그램을 사용하는 대상분야를 도메인이라고 한다.
    도메인 모델에서 모델이랑 대상을 단순화해서 표현한 것이다.
    모델은 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태이다.
    모델은 중요한 문제에 집중할 수 있도록 필요한 지식만 재구성한 것이다. 즉, 추상화하고 단순화한 것이다.

    도메인 모델은 사용자가 프로그램을 사용하는 대상 영역에 대한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태이다. 

    도메인 모델은 소프트웨어가 목적하는 영역내의 개념과 개념간의 관계, 다양한 규칙이나 제약 등을 주의 깊게 추상화한 것이다. 
    도메인 모델은 소프트웨어 개발과 관련된 이해 관계자들이 도메인에 대해 생각하는 관점이다.

    도메인 모델을 기반으로 설계하고 구현하는 것은 사용자가 도메인을 바라보는 관점을 그대로 코드에 반영할 수 있게 한다.
    도메인 속의 개념과 관계가 코드 속에 녹아 있기 때문에 도메인이 알려주는 길을 따라가면 코드 속에서 길을 잃지 않을 수 있다.
    또 도메인을 바라보는 사용자의 관점은 도메인의 본빌적인 측면을 가장 잘 이해하고 있기때문데 
    도메인 모델이 제공하는 구조는 상대적으로 안정적이다.

    유스케이스 192p
    기능적 요구사항이란 시스템이 사용자에게 제공해야하는 기능의 목록을 정리한 것이다.

     

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

    도메인 모델은 구조를, 유스케이스는 협력의 출발점인 시스템 책임을 제공한다.
    사스템에 할당된 커다란 책임은 이제 시스템 안의 작은 규모의 객체들이 수행해야 하는 더 작은 규모의 책임으로 세분화된다.
    그렇다면 어떤 객체를 선택할 것인가? 이 시점에서 도메인 모델이 무대에 등장한다.
    우리는 도메인 모델에 포함된 개념을 은유하는 소프트웨어 객체를 선택해야 한다.
    이것은 소프트웨어와 코드 사이의 표현적 차이를 줄이는 첫걸음이다. 

    책임 할당의 원칙

    기능 = 책임 

    예를 들어, 이자를 계산하는 책임을 가진 객체는 이자율이 될 것이며, 이자는 이자율에 의해 생성될 것이다.
    왜 이자를 계산하는 책임을 이자율 객체에 할당하는가? 
    책임 할당의 기본 원칙은 책임을 수행하는 데 필요한 정보를 가진 객체에세 그 책임을 할당하는 것이기 때문이다.
    이것은 관련된 상태와 행동을 함께 캡슐화하는 자율적인 객체를 낳는다.

    도메인 모델을 구성하는 개념은 비지니스가 없어지거나 완전히 개편되지 않는 한 안정적으로 유지된다.
    정기예금, 계자, 이자, 이자율이란 개념은 정기예금이란 금융상품이 없어지거나 완전히 개편되지 않는 이상
    안정적으로 유지되는 개념이다,

    도메인 모델의 이같은 특징은 도메인 모델을 중심으로 객체 구조를 설계하고 
    유스케이스의 기능을 객체의 책임으로 분배하는 기본적인 객체지향 설계 방식의 유연함을 잘 보여준다.

    반응형
Designed by Tistory.