소프트웨어 개발을 하다 보면 “객체 지향 설계(Object-Oriented Design)”라는 말을 자주 듣게 됩니다. 그러나 객체 지향 설계는 단순히 “객체를 나눠서 코딩하는 거야”를 넘어서 그 이상의 철학과 원칙을 담고 있습니다.
쉽게 말해, 객체 지향 설계는 “객체”라는 독립적인 단위들이 서로 협력해서 하나의 목표를 이루도록 만드는 설계 방식입니다.
객체란?
먼저, 객체(Object)는 단순히 데이터와 기능을 묶어놓은 덩어리가 아닌 책임과 역할을 가진 자율적인 존재입니다. 그리고 이 객체들은 서로 메시지를 주고받으며 협력합니다.
객체를 나눌 때의 기준
객체를 나눌 때 가장 중요한 건 책임과 역할입니다.
예를 들어, E-commerce에서 “손님”이라는 객체가 있다고 가정했을 때.
- 책임: 손님 객체의 책임은 상품을 선택하고 주문하는 것.
- 역할: 이런 책임들이 모여 손님 객체의 역할을 정의합니다.
하지만 손님 객체에 하나에 모든 책임을 전가 하면 **단일 책임 원칙(Single Responsibility Principle)에 위반하기 때문에 다른 책임은 적절한 객체에게 위임해야 합니다.
예시 1: 손님 객체
- 손님 객체는 상품 객체에 메시지를 보내 상품 리스트를 요청합니다.
- 받은 상품 리스트에서 원하는 상품을 골라 장바구니 객체에 추가합니다.
- 마지막으로, 장바구니에 담긴 상품 정보를 주문 객체에 전달해 주문을 완료합니다.
이처럼 객체는 각자의 책임과 역할을 바탕으로 서로 협력하며, 시스템의 목표를 이루는 데 기여합니다.
예시 2: 주문 객체
E-commerce 시스템에서 “주문”이라는 객체는 행위나 상태를 시스템적으로 표현한 추상적 객체로서 손님과 상품, 결제 정보를 연결하는 중요한 역할을 합니다.
- 책임: 주문 객체의 책임은 주문 정보를 관리하고, 결제 및 배송 프로세스를 처리하는 것입니다.
- 역할: 주문 객체는 손님, 상품, 결제 객체와 협력하여 주문 프로세스를 완성합니다.
주문 객체의 협력 과정:
- 손님(Customer)
- 손님은 상품을 선택하고 주문을 생성하는 역할을 합니다.
- 손님 객체는 상품 객체에 메시지를 보내 상품 정보를 요청하고, 주문 객체를 생성합니다.
- 상품(Product)
- 상품 객체는 상품의 이름, 가격, 재고 등 정보를 제공합니다.
- 손님이나 주문 객체가 요청하면 필요한 정보를 반환합니다.
- 주문(Order)
- 주문 객체는 손님이 선택한 상품 정보를 포함하며, 결제 객체에 결제를 요청합니다.
- 주문은 손님과 상품, 결제 객체를 연결하는 중심적인 역할을 합니다.
- 결제(Payment)
- 결제 객체는 주문 객체로부터 결제 요청을 받아 결제를 처리합니다.
- 결제 상태(성공/실패)를 주문 객체에 반환합니다
이처럼 객체는 각자의 책임과 역할을 바탕으로 서로 협력하며, 시스템의 목표를 이루는 데 기여합니다.
객체의 책임: 크레이그 라만의 관점
크레이그 라만(Craig Larman)
크레이그 라만은 객체 지향 설계와 책임 주도 설계(Responsibility-Driven Design)의 대가로, 객체 지향 설계의 핵심 원칙을 정리한 소프트웨어 공학자입니다. 그의 저서 *”Applying UML and Patterns”*는 객체 지향 설계의 바이블로 불리며, 객체의 책임과 협력에 대한 명확한 가이드를 제시합니다.
크레이그 라만은 객체의 책임을 크게 두 가지로 나눴습니다: **아는 것(knowing)**과 하는 것(doing).
1. 아는 것 (Knowing)
객체는 자신이 알아야 할 것들에 대해 책임을 집니다.
- 사적인 정보에 관해 아는 것: 객체는 자신의 내부 상태나 데이터를 알고 있어야 합니다. 예를 들어, 손님의 이름, 나이, 주문 내역 등
- 관련된 객체에 대해 아는 것: 객체는 자신과 관련된 다른 객체를 알고 있어야 합니다.
- 자신이 유도하거나 계산할 수 있는 것에 관해 아는 것: 객체는 자신의 데이터를 기반으로 계산하거나 유도할 수 있는 정보를 알고 있어야 합니다.
2. 하는 것 (Doing)
객체는 자신이 해야 할 행동에 대해 책임을 집니다.
- 스스로 하는 것: 객체는 자신의 데이터를 처리하거나 계산을 수행할 수 있어야 합니다.
- 다른 객체의 행동을 시작시키는 것: 객체는 다른 객체에게 메시지를 보내 행동을 유발할 수 있어야 합니다. 예를 들어 손님 객체가 상품 객체에 메시지를 보내 상품 리스트를 요청.
- 다른 객체의 활동을 제어하고 조절하는 것: 객체는 다른 객체의 행동을 조정하거나 제어할 수 있어야 합니다. 예를 들어, 주문 객체는 장바구니 객체의 데이터를 확인하고 이를 기반으로 주문을 생성할 수 있어야 합니다.
결국 객체의 책임은 “무엇을 알아야 하는가”와 “무엇을 해야 하는가”로 나뉘며, 이를 명확히 정의하는 것이 객체 지향 설계의 핵심입니다.
객체의 자율적이란?
객체는 자율적이어야 합니다.
즉, 객체는 자신의 책임과 역할을 스스로 수행하며, 다른 객체에 의존하거나 위탁하지 않아야 해요. 이를 위해 객체는 캡슐화(encapsulation)라는 개념을 사용합니다.
캡슐화
캡슐화는 객체의 내부 구현을 외부에서 숨기고, 필요한 정보나 기능만 외부에 노출하는 것을 말합니다.
- 객체는 자신의 상태(데이터)를 직접 노출하지 않고, 메서드를 통해서만 접근할 수 있도록 제한합니다.
- 이렇게 하면 객체의 내부 구현이 변경되더라도 외부에 영향을 주지 않습니다.
예를 들어, 장바구니 객체가 상품 리스트를 관리한다고 가정 했을 때.
- 외부에서는 상품 리스트에 직접 접근할 수 없고, 상품을 추가하거나 삭제하는 메서드를 통해서만 접근할 수 있습니다.
- 이렇게 하면 상품 리스트의 내부 구조가 변경되더라도, 외부에서는 이를 알 필요가 없고 시스템의 안정성이 높아집니다.
캡슐화는 객체의 자율성을 보장하며, 시스템의 유지보수성과 확장성을 높이는 데 중요한 역할을 합니다.
객체 지향 설계란?
객체 지향 설계는 자율성을 가진 객체들이 서로 협력하도록 시스템을 분할하는 설계 방식입니다.
이 설계의 핵심은 객체 간의 책임과 역할을 적절히 나누고, 이를 통해 객체들이 유기적으로 협력하도록 만드는 것입니다.
객체 지향 설계의 특징
- 객체는 혼자서는 의미가 없다 객체는 다른 객체와의 협력을 통해서만 자신의 역할을 수행할 수 있습니다. 예를 들어, 손님 객체는 상품 객체, 장바구니 객체, 주문 객체와 협력해야만 상품 주문이라는 목표를 달성할 수 있습니다.
- 역할과 책임의 분리 객체는 자신의 역할과 책임을 명확히 정의하고, 이를 기반으로 다른 객체와 상호작용합니다. 이를 통해 시스템은 더 유연하고 확장 가능한 구조를 가지게 됩니다.
객체의 구성 요소
객체는 다음 세 가지 요소로 구성됩니다:
- 상태(State)
객체가 가지고 있는 데이터나 속성을 의미합니다. 예를 들어, 손님 객체의 상태는 이름, 나이, 주문 내역 등이 될 수 있습니다. - 행동(Behavior)
객체가 수행할 수 있는 동작이나 기능을 의미합니다. 예를 들어, 손님 객체는 상품을 선택하거나 주문을 요청하는 행동을 가질 수 있습니다. - 식별자(Identifier)
객체를 고유하게 식별할 수 있는 값입니다. 예를 들어, 손님 객체의 ID나 주문 번호 등이 식별자가 될 수 있습니다.
객체는 자신의 행동을 기반으로 다른 객체와 상호작용 하며, 이를 통해 협력을 이루어냅니다.따라서 객체 지향 설계는 객체의 상태가 아닌 행동을 먼저 정의하는 데 초점을 맞춥니다.
마무리
객체 지향 설계는 단순히 객체를 나누는 게 아니라, 객체 간의 협력을 통해 시스템의 목표를 달성하도록 만드는 설계 철학입니다.
객체의 책임과 역할을 명확히 정의하고, 이를 기반으로 협력을 설계하면 더 유연하고 유지보수하기 쉬운 시스템을 만들 수 있습니다.