본문 바로가기

책을 읽어보자/객체지향의 사실과 오해

[우테코 권장도서] 객체지향 사실과 오해 5장

5장 책임과 메시지

지금 현재 상태가 헤르페스나고 목구멍에는 구멍나고 졸려죽겠다. 그리고 책읽는것도 밀렸었어서 모든걸 정리할 힘이 나지않고

거기다가 이책은 읽을때마다 느끼는거지만 술취한 사람과 대화하는 느낌으로 한말 또하고 한말 또 한다.

근데 또 중간에 의미를 툭툭던져서 넋을 놓고 읽을수는 없는 개꼰대 교수님과의 술자리 같다.

그래서 아주 핵심적인 내용들을 키워드와 함께 정리해보려한다.

자율적인책임

외부에 노출된 인터페이스를 제외하고는 객체가 자율적으로 처리방법을 정하는것이 주이다.

이래야 재사용성도 올라가고 객체의 변경에 따른 다른 객체의 연쇄 변경을 막을수 있다.

여기서 자율적인 책임은 모자장수의 증언을 예시로 드는데

왕이 증언하라 라고 메시지를 던져야지

기억을 더듬어라

생각을 말로 정리해라

말해봐라

이런식으로 명령(메시지)를 하면 메모장에 증거를 적어놓고 말을못해서 필담을 하는 모자장수는 증언을 할수없다.

또한 현재 모자장수가 증언을 한다고 해서 다른 객체는 증언을 할수없어 객체를 갈아끼우는데 어려움을 겪을수 있다.

현재 스위스에 가있는 제이슨은 동영상으로밖에 증언에 참여하지 못하는데 생각을 말로 정리해라에 응답할수없다.

이럴때 그냥 추상화된 증언하라 였다면 제이슨은 동영상 편지를 보냈을것이다.

그래서 이러한 공용인터페이스와 내부구현을 명확히 나누면서 자율성을 얻어낼수있고

그 추상화의 정도를 정하는것이 개발자의 실력이라고 판단된다.

(그 일을 하는데 문제없는선에서 가장 추상적으로 올라가는것이 옳은것같다 현재 생각으로는)

추상화를 하는데 도움되는 팀으로 "어떻게가 아니라 무엇을" 이라는 키워드를 제시했다.

구체적인 방법이 아닌 그냥 어느걸 해줘라고 말하는것이다.

메시지와 메서드(내외부의 분리)

메시지는 외부에서 객체에 전달할수 있는 공용 인터페이스 이고

메서드는 내부 구현을 의미한다.

이렇게 외부 노출된 함수와 메서드를 철저히 분리해야 위에서 말한 자율성을 얻을수 있다.

즉 메서드는 외부에서 철저하게 접근할수 없도록 막아버려야한다.

그래서 리뷰어분들이 눈에 불을키고 private안단것들을 찾아다니시는것 같다.

다형성

다형성이 결국 객체지향의 핵심이 아닌가 싶다.

객체지향의 3요소로 캡슐화 상속 다형성 이라고 하는데

그냥 아니다 이거 내가 생각하기에는 다형성과 아이들이다. 거기다가 상속은 좋지만 무서운 친구다 가끔 돌아버려서 칼춤추고 다니는

어쨋든 캡슐화도 다형성을 잘 사용할수있도록 지켜야하는 항목이니 다형성이 주인공이 아닐까?

그래서 다형성이 뭔지 뚜렷하게 말해보자면

다형성: 서로 다른유형의 객체가 동일한 메시지에 대해 서로 다르게 반응하는 것을 의미

-> 서로 다른 타입에 속하는 객체들이 동일한 메시지를 수신할경우 서로 다른메시지를 통해 메시지를 처리할수있는 메커니즘

즉 이제 같은 역할(인터페이스? 꼭 인터페이스 만은 아니지만 추상화 할수있는 단위)에 속해있다면 어떤 일들을 할수있다는것은 보장되어있고

(메시지를 처리할수있고) 그렇다면 그 최소조건을 지킨객체라면 실제 타입은 무엇이든 다 넣어서 동작시킬수있다(세부구현은 다르다.)

즉 추상화를 열어놓는다면 그 이후에 구현을 맘대로 바꿀수 있는 창구가 열리는것이다.

그래서 다형성을 잘활용한다면 유연하고 확장가능하고 재사용성을 높일수 있다.

그리고 이는 느슨한 결합이라고 말할수도 있다.

메시지

계속 책에서 말해온 외부에 노출되어있는 함수들이다.

이런것들을 죄다 추상화를 시켜서 상위타입을 만들어놔야 바꿀수있는 창구가 열리므로 추상화는 필수이고 그것을 어떻게 할것인지를 계속 설명하고있다.

책임주도 설계를 하라고 마르고 닳도록 설명하는데 결국 메시지(외부에서 접근할수있는 기능목록)을 먼저 쫙 정리하고 그것들을 적당히 묶어서 객체에다가 분배하는 방식을 사용한다면 우리가 객체부터 만들고 기능을 빚어나가는때 겪는 실수나 이상한 행동을 줄일수 있다는것이다.

애초에 객체지향을 모르는 상태에서 본다면 그냥 기능을 구현하기위해 그냥 객체의 상태를 꺼내쓰고 그냥 객체도 캡슐화해서 꽁꽁 뭉처야하는 대상이 아니라

코드적는 템플릿에 불과하다.

그래서 그런것들을 객체 지향적으로 타파시키기 위해서 그렇게 메시지와 책임주도 설계를 부르짖는다고 생각한다.

물론 설계라는것은 어렵고 책임주도설계도 어렵다. 하지만 그게 좀더 쉬운방법이니 쫓아가볼 가치가 있음을 우테코 미션을 통해서 뼈져리게 느낀다.

내가 쓴 코드는 일단 내가 만든거라 단점이 안보인다.(시간을 많이 들였다는 전제하에) 하지만 남이보면 또 헛점 투성이다.

근데 애초에 외부접근 기능부터 (필요한 일부터 쭈루룩 정리하고) 그것을 뺀 구현은 다 private하게 캡슐화 시켜버린다면.

우리가 생각하는 아름다운 구현을 이뤄낼수있다.

맨날 디미터의법칙 위반이네 뭐네 하는것도 결국 외부에서 일을 시킬때 내부의 행위나 상테에 대해서 모른다고 가정하는것이 맞다는것이다.

이걸 구체적으로 이야기하는게 . 을 많이 찍지말라는것이다.

외부에 노출된 함수 하나만 호출하면 다 해결해야지 그것을 타고타고 계속 호출해줘야한다면 외부에서 그것을 조정하고 주무르고 있는 형태이지 객체가 자율적이지 않다는것이다. 아까 모자장수에게 증언법을 다 왕이 알려주는 형태와 같아지는것이다.

인터페이스

인터페이스를 여태까지 역할 아닌가라고 이야기했는데 이제는 생각이 바뀌었다.

인터페이스는 역할을 가장 잘 설명하고 가장 가까운 것이지만 추상화가 가능한 단위라면 추상클래스든 클래스든 상관없다.(하지만 클래스라고 하면 또 어떤사람들의 발작버튼일것이다. -> 클래스를 사실 역할의 용도로 쓰면 유명무실 하기 때문에 사실상 클래스는 제외해도된다.)

어쩃든 개발을 진행하면서 객체지향을 따르고 유연하게 만드려면 모든 객체를 만들기전에 일단 인터페이스를 만들고 그것을 구현하는 객체로 시작해야한다고 생각한다.

하지만 그것은 비용이 너무많이 들으니 진짜 변화가 많은 부분만 인터페이스를 사용하여 추상화 시켜주는것이라고 생각한다.

결국 이말은 자주 변화되는 부분이라고 예상된다면 무조건 인터페이스든 뭐든 통해서 추상화가 필수라는것이다.

그렇다면 우리가 인터페이스를 만들지 않고도 최대한 재사용성을 올리는 방법은 무엇일까? -> 애초에 외부에 노출될 것들만 간추려서 정리하고 그후 구현한다면 인터페이스를 이용하지는 않지만 비슷한 효과를 불러일으킬수 있지않을까 생각한다.

즉 철저히 내부 상태나 메서드를 캡슐화 시켜보자 (그리고 이런거 어려우니까 미리 외부노출 함수들(기능목록)을 만들어놓고 메서드로 해결해보자)

캡슐화

맨날 캡슐화 캡슐화 하는데 그게 그래서 뭔데

또 같은 이야기지만 외부 노출 함수와 메서드,상태 를 철저히 분리해서 객체 내부의 변경에 대한 외부의 연쇄적인 변경을 최소화 하라는것이다.

즉 외부의 변화는 외부노출 함수가 변화하는것 이외에는 있으면 안된다.

이런 말들을 인터페이스와 추상화 뒤에다가 내부 를 감춰서 변경에 대응하는것이다.