Open j03y14 opened 8 months ago
객체지향은 클래스가 아니라 객체를 바라보는 것 에서 부터 시작한다.
객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 존재로 바라보아야한다.
협력에 참여하는 객체들에게 얼마나 적절한 역할과 책임을 부여하는지 에 달려있다.
대부분의 사람들은 “객체지향이란 실세계를 직접적이고 직관적으로 모델링할 수 있는 패러다임” 이라고 하지만,
애플리케이션을 개발하면서 객체에 직접적으로 대응되는 실세계의 사물을 발견할 확률은 그다지 높지 않다.
객체지향의 목표는 실세계를 모방하는 것이 아니다. 새로운 세계를 창조하는 것이다.
다만 객체를 스스로 생각하고 스스로 결정하는 현실의 생명체에 비유하는것은 상태와 행위를 캡슐화 하는 소프트웨어 객체의 자율성을 설명하는 데 효과적이다.
사람이 암묵적인 약속과 명시적인 계약을 기반으로 협력하며, 메시지를 주고 받는 것은 객체들의 관계를 설명하는데 적합하다.
따라서 실세계의 사물의 모방이라는 관점은 객체지향이라는 세계를 이해하는데 도움을 줄 수 있다.
손님은 커피를 주문하고, 캐시어는 주문을 받고, 바리스타는 커피를 제조한다.
바리스타는 제조가 끝난 커피를 캐시어에게 전달하고, 캐시어는 손님에게 소식을알린다.
이 과정에는 암묵적임 협력 관계가 존재한다.
그리고 각각의 역할이 존재해서, 이벤트를 달성 할 수 있다.
각각의 사람은 맡은 책임을 다한다.
역할과 책임?(경계가 애매하게 느껴진다)
요청은 연쇄적으로 발생한다.
다른사람의 요청에 응답한다.
요청은 연이어 발생하기 떄문에 응답 역시 요청과 반대방향으로 연쇄적으로 전달된다.
사람은 협력의 과정에서 특정한 역할을 부여받는다.
역할은 어떤 협력에 참여하는 사람이 협력안에서 차지하는 책임이나 의무를 의미한다.
역할이라는 단어는 의미적으로 책임이라는 개념을 내포한다.
특정한 역할은 특정한 책임을 암시한다.
사람을 객체로, 요청을 메시지로, 요청을 처리하는 방식을 메서드로 바꾸면 객체지향의 문맥으로 옮겨올 수 있다.
일상생활의 목표는 사람들의 협력을 통해 달성되며, 목표는 더 작은 책임으로 분할되고 책임은 수행할 수 있는 적절한 역할을 가진 사람에 의해 수행된다.
“어떤 객체도 섬이 아니다”
객체치향 설계는 적절한 객체에게 적절한 책임을 할당하는 것에서 시작된다.
책임은 객체지향 설계 품질의 가장 중요한 요소이다.
역할은 관련성 높은 책임의 집합이다.
객체는 협력 공동체의 일원으로서
충분히 협력적이여야한다.
전지 전능한 객체는 복잡도에 의해 자멸하고만다. -> 객체를 잘 나누어야한다.
충분히 자율적이어야 한다.
자기 스스로의 원칙에 따라 어떤 일을하고, 자기 스스로 통제하여 절제하는 것 -> 메서드와 상태를 잘 정의해야한다.
흔히들 객체를 상태와 행동을 함께 지닌 실체 라고 한다.
객체가 협력에 참여하기위해 어떤 행동을 해야한다면 그 행동을 하는 데 필요한 상태도 함께 지니고 있어야 한다
객체가 어떤 행동을 하기위해 필요한 상태를 알지 못하면 안된다.
객체지향은 데이터와 프로세스를 객체라는 틀안에 묶어 놓음으로서 객체의 자율성을 보장한다.
객체는 협력을 위해 다른 객체에게 메세지를 전송하고 수신한다.
객체가 수신된 메시지를 처리하는 방법을 메서드 라고 한다.
클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과하다.
헌준 질문: 객체는 '사람'이다 역할이 '바리스타'인데 책임이 '커피 제조', '제조된 커피 전달'
... '사람'은 다른 역할도 할 수있다.
여러가지 역할을 할 수 있는 객체가 뭔지 모르겠음.
재윤: 일단, 클래스로 어떻게 만들어지는지는 생각하려고 하지말자.
객체 지향이란 '무엇을 할지'를 바라보는 것이라고 생각한다 무엇을 하는지를 나열해서 프로그램을 돌아가도록 하는 것
'무엇을 할지'와 '어떻게 할지'를 분리하고 '무엇을 할지'를 기준으로 설계하면 자율성이 올라가고, 객체가 여러가지 역할을 할 수 있게된다.
결국 클래스로 생각해보면 -> 클래스의 퍼블릭 메서드가 '무엇을 하는지'를 나타낸다. -> 클래스의 인터페이스나 추상 클래스는 클래스의 역할을 나타낸다. -> 해당 클래스의 구현은 자율적으로 -> 외부에서 클래스내부는 모르고 무엇을 하는지 만 안다.
재윤 의문: 객체가 협력하는 과정 속에서 스스로 판단하고 결정하는 자율적인 존재로 남기 위해서 필요한 // 행동과 상태를 함께 지니고 있어야 한다. 그런가?
함수 안에 지역 변수를 선언하면, 그건 행동과 상태를 함께 지니고 있는것인가?
헌준: 객체의 자율성을 보장할 수 있는 이유는, 내가 필요한거를 내가 가지고 있어서이다. 내가 필요한 상태가 다른 객체에게 있으면 자율성은 낮아진다. 지역변수는 다른 객체가 관여할 수 가 없는 상태라서, 논외인 것 같다.
재윤: 함수형 프로그래밍 관점에서, 함수는 외부에 의존하면 안되는데 클래스 메서드가 클래스 변수를 참조하는 것도 사이드 이펙트이다. 그렇다면 객체지향과 함수형은 공존할 수 없는 패러다임인가.
헌준: 함수형 프로그래밍에서 완전히 모든 사이드 이펙트를 없애는건 아니므로 클래스 메서드가 클래스 변수를 꼭 참조 해야할 때만 사용한다면, 공존하는 것으로 볼 수도있다.
재윤: 결국 함수 안에 지역 변수가 있으면 그것도 상태를 지니고 있는것으로 봐야하지 않나
재윤의 해석: 상태와 행동이 동시에 존재해야 자율성있는 객체다 헌준의 해석: 필요한 것을 상태나 행동을 구분하지 말고 모아둬라
재윤: 메서드랑 메시지는 뭐가달라?
헌준: 메시지는 메서드를 호출하는것 암묵적인 규칙과 명시적인 규칙이 메서드가 받는 파라미터 형식
재윤: 메세지가 '무엇을 하는지' 즉, 메서드의 인터페이스 구현체가 메서드다
메세지를 보낸다 는 인터페이스의 메서드 네임이랑 파라미터를 가지고 실행하는것 그게 어떻게 실행되는지 구현된게 메서드다
재윤이 말하는 '무엇을 하는지'는 책의 '역할' 개념과 닿아 있음
interface Barista {
// 메세지
makeCoffee(water, bean): Coffee
}
class BaristaA extends Barista {
// 메서드
makeCoffee(water, bean) {
// 커피만들기
return new Coffee();
}
}
const barista: Barista = new BaristaA();
barista.makeCoffee();
좋은 객체지향 설계는 협력에 참여하는 객체들에게 얼마나 적절한 역할과 책임을 부여하는지 에 달려있다.
실세계를 모방해서 클래스를 만들고 이를 상속하는 구조를 만드는 방향은 잘못되었고
'무엇을 하는지'(책임)생각하고, 책임에 따라 역할을 분획해서 역할을 객체에게 부여하는 방식으로 객체지향 설계를 해야한다.
협력하는 사람들 요청과 응답으로 구성된 협력 역할과 책임 역할, 책임, 협력 협력속에 사는 객체 상태와 행동을 함께 지닌 자율적인 객체 협력과 메세지 메서드와 자율성 객체지향의 본질 객체를 지향하라
헌준 협력의 관점에서 객체의 특징을 파악한다. 협력을 통해서 목적을 달성할 때 각 객체는 역할을 부여받고 책임을 다한다. 각각의 객체가 역할을 다하려면 객체가 자율적이어야하고 자율적인 객체가 되기 위해서는 객체가 필요한 상태와 행동을 가져야한다. 각각의 자율적인 객체는 메시지를 통해서 협력한다.
-> 협력의 관점에서 객체에게 필요한 구성요소가 무엇인가.
재윤: 주제: 객체지향이 어떤 것인가? 이번 장 에서만 실세계의 예시를 통해 이해하자 실세계의 예시에서 사람은 각각 역할 책임 을 가지고 협력해서 목표를 달성한다.
객체도 마찬가지로 각각의 객체들이 협력하는 관계속에서 서로의 역할을 가지고 책임을 다하면서 목적을 달성한다.
실세계 예시를 역할 책임 협력의 관점에서 보면 역할은 다른 사람으로 대체될 수 있고 역할을 어떻게 처리할지는 각각의 사람들에게 달려있고 일정한 의사소통수단을 통해 협력한다.
이런게 객체지향의 본질이다.
"실세계의 모방"은 철학적인 개념을 설명하는데는 적합하지만 실용적인 관점에서 설명을 하는데는 적합하지 않다. 어플리케이션을 개발하면서 객체에 직접적으로 대응되는 경우는 많지 않다.
그렇지만 이런 개념이 사용되는 이유는 실세계에 대한 비유가 객체지향의 다양한 측면을 이해하는데 효과적이기 때문이다.
이번 장에서는 잠시만 객체지향이 실세계의 모방이라는 개념을 차용하겠다.
협력하는 사람들
커피를 주문하고 제조하는 과정은 역할, 책임, 협력이라는 세가지 개념이 조화를 이루어 만들어낸 것이다.
역할, 책임, 협력은 객체지향에서 가장 중요한 세가지 개념이다.
요청과 응답으로 구성된 협력
하나의 문제를 해결하기 위해 다수의 역할이 필요하기 때문에 요청은 연쇄적으로 발생한다.
요청을 받은 사람은 책임을 다하면서 응답한다.
요청과 응답을 통해서 협력을 한다. 협력은 각 개인이 얼마나 요청을 성실하게 이행하는가에 달려있다.
역할과 책임
사람들은 협력하는 과정 속에서 역할을 부여받는다.
역할은 협력하는 특정한 사람이 협력 안에서 차지하는 책임과 임무를 의미한다. 역할은 책임을 내포한다. 바리스타는 커피를 만들 책임이 있고, 캐시어는 주문을 받을 책임이 있다.
사람들이 역할을 맡고 책임을 수행한다는 것은 다음과 같은 개념을 제시한다.
역할, 책임, 협력
객체지향 설계는 적절한 객체에게 적절한 책임을 할당하는 것이라고 할 수 있다.
협력속에 사는 객체
객체지향 어플리케이션의 윤곽은 역할, 책임, 협력으로 결정되지만, 실제로 협력하는 주체는 객체이다.
객체지향 어플리케이션의 아름다움을 결정하는 것은 협력이고, 협력이 얼마나 조화를 이루는지 결정하는 것은 객체이다.
객체는 다음과 같은 두가지 덕목을 갖추어야 한다. 또한 두 덕목 사이에서 균형을 이뤄야 한다.
다른 객체의 요청에 따라 행동하지만, 스스로의 판단에 따라 행동할 수 있어야 한다.
상태와 행동을 함께 지닌 자율적인 객체
흔히 객체를 상태와 행동을 함께 지닌 실체라고 한다.
객체가 협력하는 과정 속에서 스스로 판단하고 결정하는 자율적인 존재로 남기 위해서 필요한 행동과 상태를 함께 지니고 있어야 한다. ❓그런가?
자율성은 객체의 내부와 외부를 명확하게 구분하는 것으로부터 나온다. 객체는 다른 객체가 무엇을 했는지는 알지만, 어떻게 했는지는 알 수 없다.
협력과 메세지
객체지향의 세계에서 의사소통 수단은 메세지 하나이다.
메서드와 자율성
객체가 수신된 메세지를 처리하는 방법을 메서드라고 부른다.
메세지를 수신한 객체가 실행시간에 메서드를 선택할 수 있다는 점은 다른 프로그래밍 언어와 객체지향 프로그래밍 언어를 구분짓는 핵심이다.
메세지와 메서드의 분리는 객체들간의 자율성을 증진시킨다.
외부의 요청이 무엇인지를 표현하는 메세지와 요청을 처리하기 위한 구체적인 방법인 메서드를 분리하는 것은 자율성을 높이는 핵심이다.
객체지향의 본질
객체를 지향하라
클래스와 객체를 이루는 중심은 아니다.
훌륭한 객체지향 설계자가 되기 위해서는 코드를 담는 클래스의 관점에서 메세지를 주고 받는 객체의 관점으로 사고의 중심을 전환하는 것이다.
자, 이제 다시 설명해보자..