객체지향 프로그래밍을 향해
협력, 객체, 클래스
- 객체지향은 객체를 지향하는 것이다.
- 일반적인 경우 객체지향 언어에 익숙한 사람이라면 가장 먼저 어떤 클래스가 필요한지 고민할 것이다. 그 후에는 어떤 속성과 어떤 메서드가 필요한지 고민한다.
- 하지만 이것은 객체지향의 본질과 거리가 멀다. 객체지향은 말 그대로 객체를 지향하는 것이다.
- 진정한 객체지향 패러다임으로의 전환은 클래스가 아닌 객체에 초점을 맞출 때에만 얻을 수 있다. 이를 위해서는 두 가지에 집중해야 한다.
- 어떤 클래스가 필요한지를 고민하기 전에 어떤 객체들이 필요한지 고민하자.
- 클래스는 공통적인 상태와 행동을 공유하는 객체들을 추상화 한 것이다. 따라서 클래스의 윤곽을 잡기 위해서는 어떤 객체들이 어떤 상태와 행동을 가지는지를 먼저 결정해야 한다.
- 객체를 중심에 두는 접근 방법은 설계를 단순하고 깔끔하게 만든다.
- 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 일원으로 바라봐야 한다.
- 객체는 홀로 존재하는 것이 아니다. 다른 객체에게 도움을 주거나 의존하면서 살아가는 협력적인 존재다.
- 객체를 협력하는 공동체의 일원으로 바라보는 것은 설계를 유연하고 확장 가능하게 만든다. 객체지향적으로 생각하고 싶다면 객체를 고립된 존재로 바라보지 말고 협력에 참여하는 협력자로 바라봐야한다.
- 객체들의 모양과 윤곽이 잡히면 공통된 특성과 상태를 가진 객체들을 타입으로 분류하고 이 타입을 기반으로 클래스를 구현하자.
- 훌륭한 협력이 훌륭한 객체를 낳고 훌륭한 객체가 훌륭한 클래스를 낳는다.
도메인의 구조를 따르는 프로그램 구조
- 문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 도메인이라고 부른다.
- 소프트웨어는 사용자가 원하는 어떤 문제를 해결하기 위해 만들어진다.
- 영화 예메 시스템의 목적은 영화를 좀 더 쉽고 빠르게 예매하려는 사용자의 문제를 해결하는 것
- 객체지향 패러다임이 강력한 이유는 요구사항을 분석하는 초기 단계부터 프로그램을 구현하는 마지막 단계까지 객체라는 동일한 추상화 기법을 사용할 수 있기 때문이다
- 요구사항과 프로그램을 객체라는 동일한 관점에서 바라볼 수 있기 때문에 도메인을 구성하는 개념들이 프로그램의 객체와 클래스로 매끄럽게 연결될 수 있다.
클래스 구현하기
- 클래스를 구현하거나 다른 개발자에 의해 개발된 클래스를 사용할 때 가장 중요한 것은 클래스의 경계를 구분 짓는 것이다.
- 클래스는 내부와 외부로 구분되며 훌륭한 클래스를 설계하기 위한 핵심은 어떤 부분을 외부에 공개하고 어떤 부분을 감출지를 결정하는 것이다.
[클래스의 내부와 외부를 구분해야하는 이유]
- 경계의 명확성이 객체의 자율성을 보장하기 때문이다.
- 더 중요한 이유로 프로그래머에게 구현의 자유를 제공하기 때문이다.
자율적인 객체
- 객체는 상태와 행동을 함께 가지는 복합적인 존재라는 것을 꼭 알아야 한다.
- 객체가 스스로 판단하고 행동하는 자율적인 존재라는 점도 알아야 한다.
- 객체지향은 객체라는 단위 안에 데이터와 기능을 한 덩어리로 묶음으로써 문제 영역의 아이디어를 적절하게 표현할 수 있게 한다. 이처럼 데이터와 기능을 객체 내부로 함께 묶는 것을 캡슐화 라고 한다.
- 대부분의 객체지향 프로그래밍 언어들은 상태와 행동을 캡슐화하는 것에서 한 걸음 더 나아가 외부에서의 접근을 통제할 수 있는 접근 제어(access control) 매커니즘도 함께 제공한다. 많은 프로그래밍 언어들은 접근 제어를 통해 public, protected, private와 같은 접근 수정자를 제공한다.
[접근을 통제하는 이유]
- 객체 내부에 대한 접근을 통제하는 이유는 객체를 자율적인 존재로 만들기 위해서다.
- 객체지향의 핵심은 스스로 상태를 관리하고, 판단하고, 행동하는 자율적인 객체들의 공동체를 구성하는 것이다
- 그러기 위해서는 외부의 간섭을 최소화 시켜야한다.
- 외부에서는 객체가 어떤 상태에 놓여 있는지, 어떤 생각을 하고 있는지 알아서는 안되며 결정제 직접적으로 개입하려고 해서도 안된다.
[캡슐화와 접근제어를 통한 객체의 두 분류]
- 외부에서 접근 가능한 부분으로 이를 퍼블릭 인터페이스(public interface)라고 부른다.
- 외부에서 접근 불가능하고 오직 내부에서만 접근 가능한 부분으로 이를 구현(implmentation)이라고 부른다.
- 인터페이스와 구현의 분리원칙은 훌륭한 객체지향 프로그램을 만들기 위해 따라야 하는 핵심 원칙이다.
일반적으로 객체의 상태는 숨기고 행동만 외부에 공개해야 한다. 우리가 사용하는 프로그래밍 언어가 public이나 private이라는 키워드를 제공한다면 클래스의 속성은 private으로 선언해서 감추고 행동은 public으로 해야한다.
프로그래머의 자유
- 프로그래머의 역할을 클래스 작성자와 클라이언트 프로그래머로 구분하는 것이 용이하다.
- 클라이언트 프로그래머의 목표는 필요한 클래스들을 엮어서 애플리케이션을 빠르고 안정적으로 구축하는 것이다.
- 클래스 작성자는 클라이언트 프로그래머에게 필요한 부분만 제공하고 나머지는 숨겨야 한다.
- 클라이언트 프로그래머가 숨겨놓은 부분에 마음대로 접근할 수 없도록 방지함으로써 클라이언트 프로그래머에 대한 영향을 걱정하지 않고도 내부 구현을 마음대로 변경할 수 있다 이를 구현 은닉이라고 한다.
[구현은닉]
- 구현 은닉은 클래스 작성자와 클라이언트 프로그래머 모두에게 유용한 개념이다.
- 클래스 작성자는 인터페이스를 바꾸지 않는 한 외부에 미치는 영향을 걱정하지 않고도 내부 구현을 마음대로 변경할 수 있다.
[설계가 필요한 이유]
- 설계가 필요한 이유는 변경을 관리하기 위해서라는 것을 다시한번 기억하자 !
협력에 관한 이야기
- 객체는 다른 객체의 인터페이스에 공개된 행동을 수행하도록 요청(request)할 수 있으며 요청을 받은 객체는 자율적인 방법에 따라 요청을 처리한 후 응답(response)한다.
- 다른 객체에게 요청이 도착할 때 해당 객체가 메시지를 수신 했다고 말한다.
- 이처럼 수신된 메시지를 처리하기 위한 자신만의 방법을 메서드라고 한다.