오브젝트 독서회 2회차
Intro
오브젝트 독서회 2회차를 진행했습니다.
독서회는 계속해서 새로운 환경에서 새로운 영감을 얻기 위해서 되도록 장소를 겹치지 않고 바꿔가면서 진행하고 싶었습니다.
이번에도 스페이스 클라우드라는 서비스를 통해 세상의 모든 스터디에서 진행했습니다.
2번 방을 사용했으며, 방 자체는 지난 스터디룸보다 깔끔했습니다.
하지만 지난 스터디룸은 원두 아메리카노 무제한 이용이 가능했고, 방에 에어컨이 있었는데 이번 장소는 에어컨이 없었습니다.
원래는 지난 주에 2회차 독서회를 하기로 했지만, 맴버들의 개인사유로 1주 뒤로 미루게 되었습니다.
스터디룸에서 다행히 환불을 하지 않는다는 조건으로 1주 뒤로 미뤄주어 비용손해 없이 스터디룸을 이용했습니다.
@아메리카노 님께서 휴가로 불참하셨고, 독서회 내용을 댓글로 정리해주신다고 하셨습니다.
@eundini93 님께서 음료를 제공해주셨습니다. 감사합니다.
이번에는 모두 목표한 2장을 사전에 읽어오고 19시 20분까지 정리 한 뒤 개인 독후감을 발표하고 이어서 관련된 이야기를 진행했습니다.
지난 독서회에서 시간을 제한시간 없이 자유롭게 이용해도 되겠다는 피드백이 있었고 4명이서 진행했기 때문에 편하게 2장에 대한 나눔을 진행했습니다.
독후감 문장
38P
앞으로의 설명을 위해 '영화’와 '상영’이라는 용어를 구분할 필요가 있을 것 같다.
40P
할인을 적용하기 위해서는 할인 정책을 함께 조합해서 사용한다.
이번 장의 목표는 지금까지 설명한 요구사항을 객체지향 프로그래밍 언어를 이용해 구현하는 것이다.
41P
진정한 객체지향 패러다임으로의 전환은 클래스가 아닌 객체에 초점을 맞출 때에만 얻을 수 있다.
어떤 클래스가 필요한지를 고민하기 전에 어떤 객체들이 필요한지 고민하라. 클래스는 공통적인 상태와 행동을 공유하는 객체들을 추상화한 것이다.
객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 일원으로 봐야 한다.
문제를 해결하기 위해 사용자가 프로그램을 사용하는 분야를 도메인이라고 부른다.
42P
일반적으로 클래스의 이름은 대응되는 도메인 개념의 이름과 동일하거나 적어도 유사하게 지어야 한다.
도메인의 개념과 관계를 반영하도록 프로그램을 구조화해야 하기 때문에 그림 2.4와 같이 클래스의 구조는 도메인의 구조와 유사한 형태를 띠어야 한다.
43P
여기서 주목할 점은 인스턴스 변수의 가시성은 private이고 메서드의 가시성은 public이라는 것이다.
클래스를 구현하거나 다른 개발자에 의해 개발된 클래스를 사용할 때 가장 중요한 것은 클래스의 경계를 구분 짓는 것이다.
클래스는 내부와 외부로 구분되며 훌륭한 클래스를 설계하기 위한 핵심은 어떤 부분을 외부에 공개하고 어떤 부분을 감출지를 결정하는 것이다.
경계의 명확성이 객체의 자율성을 보장하기 때문이다.
44P
객체가 상태와 행동을 함께 가지는 복합적인 존재라는 것이다.
객체가 스스로 판단하고 행동하는 자율적인 존재라는 것이다.
객체지향의 핵심은 스스로 상태를 관리하고, 판단하고, 행동하는 자율적인 객체들의 공동체를 구성하는 것이다. 객체가 자율적인 존재로 우뚝 서기 위해서는 외부의 간섭을 최소화해야 한다. 외부에서는 객체가 어떤 상태에 놓여있는지, 어떤 생각을 하고 있는지 알아서는 안 되며, 결정에 직접적으로 개입하려고 해서도 안 된다. 객체에게 원하는 것을 요청하고는 객체가 스스로 최선의 방법을 결정할 수 있을 것이라는 점을 믿고 기다려야 한다.
뒤에서 살펴보겠지만 인터페이스와 구현의 분리(separation of interface and implementation) 원칙은 훌륭한 객체지향 프로그램을 만들기 위해 따라야 하는 핵심 원칙이다.
45P
프로그래머의 역할을 클래스 작성자와 클라이언트 프로그래머로 구분하는 것이 유용하다.
객체의 외부와 내부를 구분하면 클라이언트 프로그래머가 알아야 할 지식의 양이 줄어들고 클래스 작성자가 자유롭게 구현을 변경할 수 있는 폭이 넓어진다.
설계가 필요한 이유는 변경을 관리하기 위해서라는 것을 기억하라.
47P
그 개념이 비록 하나의 인스턴스 변수만 포함하더라도 개념을 명시적으로 표현하는 것은 전체적인 설계의 명확성과 유연성을 높이는 첫걸음이다.
48P
객체지향 프로그램을 작성할 때는 먼저 협력의 관점에서 어떤 객체가 필요한지를 결정하고, 객체들의 공통 상태와 행위를 구현하기 위해 클래스를 작성한다.
49P
객체가 다른 객체와 상호작용할 수 있는 유일한 방법은 메시지를 전송(send a message) 하는 것뿐이다. 다른 객체에게 요청이 도착할 때 해당 객체가 메시지를 수신(receive a message) 했다고 이야기한다. 메시지를 수신한 객체는 스스로의 결정에 따라 자율적으로 메시지를 처리할 방법을 결정한다. 이처럼 수신된 메시지를 처리하기 위한 자신만의 방법을 메서드(method) 라고 부른다.
52P
부모 클래스에 기본적인 알고리즘의 흐름을 구현하고 중간에 필요한 처리를 자식 클래스에게 위임하는 디자인 패턴을 Template Method 패턴이라고 부른다.
59P
여기서 이야기하고 싶은 것은 코드의 의존성과 실행 시점의 의존성이 서로 다를 수 있다는 것이다. 다시 말해 클래스 사이의 의존성과 객체 사이의 의존성은 동일하지 않을 수 있다.
한 가지 간과해서는 안 되는 사실은 코드의 의존성과 실행 시점의 의존성이 다르면 다를수록 코드를 이해하기 어려워진다는 것이다. 코드를 이해하기 위해서는 코드뿐만 아니라 객체를 생성하고 연결하는 부분을 찾아야 하기 때문이다. 반면 코드의 의존성과 실행 시점의 의존성이 다르면 다를수록 코드는 더 유연햊고 확장 가능해진다. 이와 같은 의존성의 양면성은 설계가 트레이드오프의 산물이라는 사실을 잘 보여준다.
@Vincent @freebear @muki4742 @eundini93
설계가 유연해질수록 코드를 이해하고 디버깅하기는 점점 더 어려워진다는 사실을 기억하라.
여러분이 훌륭한 객체지향 설계자로 성장하기 위해서는 항상 유연성과 가독성 사이에서 고민해야 한다.
61P
인터페이스는 객체가 이해할 수 있는 메시지의 목록을 정의한다는 것을 기억하라.
63P
다형성이란 동일한 메시지를 수신했을 때 객체의 타입에 따라 다르게 응답할 수 있는 능력을 의미한다. 따라서 다형적인 협력에 참여하는 객체들은 모두 같은 메시지를 이해할 수 있어야 한다. 다시 말해 인터페이스가 동일해야 한다는 것이다.
이를 지연 바인딩 또는 동적 바인딩이라고 부른다. 그에 반해 진통적인 함수 호출처럼 컴파일 시점에 실행될 함수나 프로시저를 결정하는 것을 초기 바인딩 또는 정적 바인딩이라고 부른다. 객체지향이 컴파일 시점의 의존성과 실행 시점의 의존성을 분리하고, 하나의 메시지를 선택적으로 서로 다른 메서드에 연결할 수 있는 이유가 바로 지연 바인딩이라는 메커니즘을 사용하기 때문이다.
64P
인터페이스를 재사용할 목적이 아니라 구현을 재사용할 목적으로 상속을 사용하면 변경에 취약한 코드를 낳게 될 확률이 높다.
67P
따라서 책임의 위치를 결정하기 위해 조건문을 사용하는 것은 협력의 설계 측면에서 대부분의 경우 좋지 않은 선택이다.
추상화를 중심으로 코드의 구조를 설계하면 유연하고 확장 가능한 설계를 만들 수 있다.
설계가 유연해질수록 코드를 이해하고 디버깅하기는 점점 더 어려워진다는 사실을 기억하라.
여러분이 훌륭한 객체지향 설계자로 성장하기 위해서는 항상 유연성과 가독성 사이에서 고민해야 한다.
61P
인터페이스는 객체가 이해할 수 있는 메시지의 목록을 정의한다는 것을 기억하라.
63P
다형성이란 동일한 메시지를 수신했을 때 객체의 타입에 따라 다르게 응답할 수 있는 능력을 의미한다. 따라서 다형적인 협력에 참여하는 객체들은 모두 같은 메시지를 이해할 수 있어야 한다. 다시 말해 인터페이스가 동일해야 한다는 것이다.
이를 지연 바인딩 또는 동적 바인딩이라고 부른다. 그에 반해 진통적인 함수 호출처럼 컴파일 시점에 실행될 함수나 프로시저를 결정하는 것을 초기 바인딩 또는 정적 바인딩이라고 부른다. 객체지향이 컴파일 시점의 의존성과 실행 시점의 의존성을 분리하고, 하나의 메시지를 선택적으로 서로 다른 메서드에 연결할 수 있는 이유가 바로 지연 바인딩이라는 메커니즘을 사용하기 때문이다.
64P
인터페이스를 재사용할 목적이 아니라 구현을 재사용할 목적으로 상속을 사용하면 변경에 취약한 코드를 낳게 될 확률이 높다.
67P
따라서 책임의 위치를 결정하기 위해 조건문을 사용하는 것은 협력의 설계 측면에서 대부분의 경우 좋지 않은 선택이다.
추상화를 중심으로 코드의 구조를 설계하면 유연하고 확장 가능한 설계를 만들 수 있다.
8장에서 살펴보겠지만 컨텍스트 독립성(context independency) 이라고 불리는 이 개념은 프레임워크와 같은 유연한 설계가 필수적인 분야에서 그 진가를 발휘한다.
69P
현실적으로는 NoneDiscountPolicy만을 위해 인터페이스를 추가하는 것이 과하다는 생각이 들 수도 있을 것이다.
여러분이 작성하는 모든 코드에는 합당한 이유가 있어야 한다. 비록 아주 사소한 결정이더라도 트레이드오프를 통해 얻어진 결론과 그렇지 않은 결론 사이의 차이는 크다. 고민하고 트레이드오프하라.
72P
이처럼 인터페이스에 정의된 메시지를 통해서만 코드를 재사용하는 방법을 합성이라고 부른다.
코드 재사용을 위해서는 상속보다는 합성을 선호하는 것이 더 좋은 방법이다.
객체지향이란 객체를 지향하는 것이다.
객체지향에서 가장 중요한 것은 애플리케이션의 기능을 구현하기 위해 협력에 참여하는 객체들 사이의 상호작용이다. 객체들은 협력에 참여하기 위해 역할을 부여받고 역할에 적합한 책임을 수행한다.
독서회 참여하신 분들 추가 피드백을 댓글로 남겨주세요!
아까 오프라인에서 나눔 하셨던 내용도 정리해서 올려주시면 감사드리겠습니다!