객체지향의 사실과 오해(조영호 저) 참조
객체지향의 사실과오해라는 책을 읽으며 객체에 대한 개념이 조금 더 잡힌것 같다. 같은 작가님이 쓰신 '오브젝트' 라는 책도 있는데, 그 책도 읽고 있는 중이다.
객체지향의 목표는 실세계를 모방하는 것이 아니라 새로운 세계를 창조하는 것이다.
이것이 객체지향에 대한 가장 큰 오해라고 책에서는 말하고 있다.
역할은 책임을 내포하는 개념이다.객체에 부여된 역할은 그 객체가 해야할 책임을 낳는다.
협력을 위해 특정한 역할을 맡고 적합한 책임을 수행한다는 개념에서는 중요한 개념을 제시한다.
여러 사람이 동일한 역할을 수행할 수 있다.
역할은 대체 가능하다.
바리스타의 역할
이는 책임을 수행하는 방법은 자율적으로 선택이 가능하다(요청을 받은 객체가 스스로 결정)
캐시어의 역할
한 사람이 동시에 여러 역할을 수행할 수 있다.
요청(request)와 응답(response)는 협력을 하기 위한 가장 기본적인 것이다.
요청은 연쇄적으로 발생한다. 그리고 요청에 대한 응답도 연쇄적으로 발생한다.
목표를 위해 협력에 참여하는 객체들은 역할에 맞는 책임을 수행하기 위해, 다른 객체들과 연쇄적인 요청과 응답을 하며 협력 관계를 유지한다.
전지전능한 객체? - 협력이 필요없는, 혼자서 모든 것을 할 수 있는 객체가 여기 있다. 얼핏 들으면 대단할 것 같지만 사실 이는 좋지 않다.
하나의 객체가 온갖 기능을 다 가지고 있다면 결국 그 객체는 내부의 복잡성에 의해 자멸하고 말것이다.
객체는 프로그램의 기능을 구현하기 위한 것이다. 간단한 기능도 객체 혼자 감당하기에는 복잡하고 거대하기 때문에, 다른 객체와의 협력을 통해 구현한다.
결국 협력의 품질이 객체의 품질을 결정한다. 좋은 협력이 이루어 질 수록 객체의 품질이 상승하는 것이다. 객체는 자신의 상태를 직접 관리하고 상태를 기반으로 스스로 판단하고 행동하는 행위를 수행한다.
개인적으로는 책을 읽고 가장 중요하게 느꼈던 부분이다.
객체는 협력을 하기 위해 메시지 라는 의사소통 방법을 가지고 있다. 아니 이 방법밖에 가지고 있지 못하다.
객체의 설계에 있어서 가지고 있는 데이터 설계에 집중하는 것은 좋은 객체를 만들지 못한다.
객체와 객체의 관계에서는 수동적인 관계는 없고 서로가 메시지를 주면 받은 객체가 그 메시지에 답을 할지 안할지 판단.
협력의 품질이 객체의 품질을 결정한다고 하는데, 이때 협력에 있어서 가장 중요한 것이 서로가 서로에게 보내는 '메시지' .
객체가 주고받는 메시지를 처리하는 방법은 메서드이다. 객체지향에서 메서드는 클래스 안에 포함된 함수 또는 프로시저라고 한다. 메시지를 처리한다는 것은 메시지에 대응되는 특정 메서드가 실행되는 것이다.
이렇게 메시지를 수신한 객체가 실행 시간에 메서드를 선택할 수 있다는 점은 다른 프로그래밍 언어와 객체지향 프로그래밍 언어를 구분 짓는 핵심적인 특징 중 하나이다.
또한 흔히 하는 착각중에 하나가 객체 = 클래스라는 오해이다. 이는 특히 클래스를 주로 사용하는 언어를 처음 배우는 사람들에게서 더 잘 나타난다.
클래스가 분명 중요한 개념인 것은 맞다. 객체라는 틀을 만들기 쉽게 정의해주는 것도 맞고, 하지만 객체지향을 구현하는 도구중에 하나일 뿐이지, 이것이 객체를 이루는 핵심 인것은 아니다. JavaScript 같은 프로토타입 언어는 아예 클래스가아닌 객체만 존재하는 언어도 있다.
객체의 설계부분에 있어서 중요한 점은 객체가 가져야 하는 메시지가 먼저 정의되어야 하며(객체가 협력을 위해 하는 행동), 객체에게 필요한 상태(가지고 있어야할 데이터들)를 먼저 생각하고 만들면 객체지향의 원칙을 위배할 확률이 높아진다. 이는 객체지향 초보자들이 가장 흔히 객체를 만들때 하는 실수이다.
결국 여기서 강조하는 것이 책임 주도의 설계
인데 TDD에도 이어진다고 생각한다. 테스트를 위주로 개발한다는 것은 결국 그 객체가 해야하는 행동을 정의하고 프로그래밍에 들어가는 것이기 때문에 확실히 객체의 책임 주도적이고, 메시지 중점적으로 설계가 가능하다고 본다.
또다른 개념으로 프로퍼티와 필드에 대해 확실하게 정의를 알고 넘어가게 되었다. 기존에는 프로퍼티와 필드가 사실상 동일한 개념이고 용어만 다양하게 쓰이는 줄 알고있었지만, 둘은 확실하게 차이가 있다.
어떤 클래스가 있고 그 클래스가 가지고 있는 프로퍼티 , 그리고 그 프로퍼티의 값이 필드로 받아들이면 된다.
public class People {
private int age;
private String name;
}
여기서 사람의 age와 name이라는 것은 바로 프로퍼티이고, 이것은 정적이고 변하지 않는다.
그리고 이 age와 name의 값이 들어간 프로퍼티를 바로 필드라고 생각하면된다. 그렇기 때문에 프로퍼티의 값이고, 이는 변할 수 있는 것이기에 필드는 변하는 동적인 것이다.
좀 더 책에서 설명한 것을 위주로 풀어가자면
객체의 상태를 구성하는 모든 특징들이 객체이던 객체가 아니던 통틀어 객체의 프로퍼티라 한다.
분명 책을 읽을때 보다는 객체라는 속성에대해, 그리고 그 지향점에 대해 좀 더 이해되었다. 단순히 언어를 배우며 캡슐화, 상속, 추상화, 다형성을 이야기하고 SOLID 원칙을 이야히할때보다 오히려 책을 읽고 더 이해도가 높아졌으니 말이다.
한번씩 객체에 대해 돌아보고 싶을때 읽으면 좋은 책이다. 즉 꾸준하게 필요할때 마다 다독하자. 한번 읽고 모든 것을 이해하지는 못하니깐.