[개발 상식] 객체 지향 프로그래밍이란 무엇인가?
객체 지향 프로그래밍의 흔한 오해
1) 객체는 클래스와 같다
클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 도구에 불과합니다. 여기서 타입은 객체를 분류하는 기준을 뜻합니다. 즉, 클래스는 객체를 표현하는 하나의 수단이라고 볼 수 있습니다.
2) 객체 지향은 현실 세계를 모방하는 것이다.
많은 사람들은 객체 지향 설계를 할 때, 객체를 현실 세계의 사물과 일대일 대응하여 동일하게 만들려고 노력합니다(데이터 중심의 설계). 예를 들어, 자동차는 무조건 운전자에 의해서 움직일 수 있는 수동적인 존재가 됩니다.
특정 객체가 수동적이라는 말은 A 객체가 B 객체에 지나치게 의존적이게 된다는 뜻입니다. 결국 서로 알고 있는 객체가 많아 저 결합도가 높아져 유지 보수(변경 사항이 생기면 바꿔야 할 코드가 많아진다.) 하기 나쁜 코드가 됩니다.
객체 지향이 직관적으로 이해하기 쉬운 이유
객체 지향은 우리의 현실의 개념과 맞닿아 있습니다. 결국 객체 지향적인 코드는 하나의 소설이라고 생각합니다. 소설은 현실을 기반해서 작성했기 때문에 이해할 수 있는 것처럼, 객체 지향도 현실을 기반으로 작성했기 때문에 이해하기 쉬운 것입니다.
객체 지향 프로그래밍의 핵심 키워드
객체
객체는 식별 가능한 개체 또는 사물을 뜻하며, 특징적인 행동(메서드)과 변경 가능한 상태(필드)를 갖습니다. 다른 객체와 협력하는 역할을 맡고 있으며, 역할을 맡으면 임무를 수행할 책임이 생깁니다. 이때, 객체는 본인의 책임을 충실히 수행해야 합니다.
협력, 책임, 역할
협력은 시스템 목표를 달성하거나 문제 상황을 해결하기 위해 여러 객체가 참여하여 행동하는 것입니다.
ex) 치킨을 튀겨서 손님에게 배달해야 한다.
책임은 협력 속에서 본인이 수행해야 할 임무의 내용을 알고, 수행하는 것입니다.
ex) 치킨을 튀길 요리사는 치킨을 맛있게 조리할 책임을 갖는다.
역할은 동일한 목적을 가진 책임의 묶음이며, 역할을 맡으면 임무를 수행할 책임이 생깁니다.
ex) 치킨을 조리할 책임을 가지는 역할은 요리사이다.
정리하자면 '치킨을 손님에게 배달하기'라는 시스템의 목표를 달성하기 위해, 치킨 가게 객체는 치킨을 튀기는 책임을 수행하고 배달원 객체는 손님에게 치킨을 전달하는 책임을 수행합니다.
메시지
객체는 메시지를 통해 다른 객체에 책임을 다하라고 요구합니다. 이때, 메시지를 보내는 객체는 무엇을 할지만 요구하고, 구체적으로 어떻게 하는지 요구해서는 안 됩니다. 예를 들어, 치킨 가게의 주문을 받는 직원은 요리사에게 ‘치킨 한 마리 주세요’라고 요구할 수 있지만, 치킨을 요리하는 과정까지 요구하면 안 됩니다. 단지 객체에게 특정 책임만 수행하라고 할 뿐, 어떻게 수행하는지는 전적으로 자율에 맡깁니다.
class ChickenShop {
public void cookChicken(){
//치킨을 요리하라는 메세지를 받아 요리를 시작한다.
}
public void deliverChicken(){
//치킨을 배달한다.
}
}
자율성 (의인화)
처음에 언급한 것처럼 객체는 자율적이고 능동적으로 행동할 수 있어야 합니다. 예를 들어, 현실 세계의 치킨 가게는 건물에 불과하지만, 객체 지향 세계의 치킨 가게는 스스로 치킨을 튀기고 치킨을 건네어 줄 수 있습니다.
다형성
다형성을 활용하는 목적은 서로 다른 유형의 객체가 동일한 메시지에 대해 다르게 반응하기 위해서입니다.
class EletricChickenShop extends ChickenShop {
public void cookChicken(){
//똑같은 치킨을 요리하라는 메시지를 받지만, 요리하는 방식은 다르다.
}
}
책임 주도 개발
처음에 언급한 것처럼 현실 세계를 반영하기 위한 설계를 할 때, 자칫하면 데이터 중심적인 설계를 하기 쉽습니다.
ex) 치킨집에는 요리사와 전화기, 배달원이 있어야 하며, 배달원은....
하지만 이런 사고는 서로 알고 있는 객체가 많아져 결합도가 높아질 확률이 높습니다. 따라서 아래와 같은 단계를 수행하는 책임 주도 개발을 참고하는 것이 좋습니다.
- 시스템이 사용자에게 제공해야 하는 기능인 시스템 책임을 파악합니다.
- 치킨 주문을 받아 손님에게 배달해야 한다.
- 시스템 책임을 더 작은 책임으로 분할합니다.
- 메시지를 생성합니다.
- 치킨 주문을 받는다.
- 치킨을 요리한다.
- 치킨을 손님에게 배달한다.
- 메시지를 생성합니다.
- 분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당합니다.
- 치킨 주문을 받는 대상은 치킨 가게다
- 객체가 책임을 수행하는 도중 다른 객체의 도움이 필요한 경우 이를 책임질 적절한 객체 또는 역할을 찾습니다.
- 치킨을 주문을 받고 보니, 치킨을 요리해야 한다.
- 치킨 가게는 요리사에게 치킨을 요리하라는 메시지를 보낸다.
- 요리사는 배달원에게 치킨을 배달하라는 메시지를 보낸다.
- 해당 객체 또는 역할에게 책임을 할당함으로써 두 객체가 협력하게 합니다.
- 클래스를 통해 객체를 구현, 객체 안의 메서드를 통해 메시지를 생성, 필요하면 상태도 생성
정리
객체는 현실의 개념을 추상화한 것이며, 객체끼리 서로 협력하고 역할을 맡아 책임을 수행하여 문제 상황을 해결해야 합니다. 다만, 현실의 사물과 달리 객체는 능동적이고 자율적인 존재입니다.
결국 객체지향 프로그래밍은 능동적이고 자율적인 객체들을 이용하여 새로운 세계를 창조하는 행위라고 볼 수 있습니다.
참고
'컴퓨터 공학 > 개발 상식' 카테고리의 다른 글
[개발 상식] 좋은 코드란 무엇인가? (0) | 2021.11.03 |
---|---|
[개발 상식] TDD란? (1) | 2021.10.26 |
댓글