U E D R , A S I H C RSS

Holub On Patterns/밑줄긋기

Contents

1. 소프트웨어 설계의 고고학
1.1. 설계 원칙
1.2. 의존관계
2. OO와 디자인패턴 기초 다지기
2.1. 패턴 vs 이디엄
2.2. 디자인패턴이란 무엇인가?
2.3. 패턴, 무엇이 좋은가?
2.4. 디자인에서 패턴의 역할
2.4.1. 패턴과 단순함 사이의 긴장
2.5. 패턴 분류하기
2.5.1. 디자인 일반
2.5.2. 자바를 C언어 스타일로 프로그래밍하기
2.5.3. 열린 눈으로 프로그래밍하기
2.6. 객체란 무엇인가?
2.6.1. 허튼소리!
2.6.2. 객체는 기능의 집합이다
2.6.3. 어떻게 잘못하고 있는가?
2.6.4. 어떻게 '올바르게' 할 수 있는가?
2.7. 셀룰러 오토마타
2.8. 접근 메소드와 수정 메소드는 나쁘다
2.8.1. 스스로를 표현하라
2.8.2. 자바빈즈와 스트럿츠
2.8.3. 리팩토링
2.8.4. get/set 없는 삶
2.8.5. 언제 getter와 setter를 사용해도 괜찮은가?
2.8.6. getter/setter 이슈 정리
3. 인터페이스로 프로그래밍하기 그리고 몇 개의 생성 패턴
3.1. 왜 Extends가 나쁜가?
3.2. 인터페이스 vs. 클래스
3.2.1. 유연성의 상실
3.2.2. 결합도
3.2.3. 깨지기 쉬운 기반 클래스 문제
3.2.4. 다중 상속
3.2.5. 프레임워크
3.2.6. Template method와 Factory Method 패턴
3.2.7. 깨지기 쉬운 기반 클래스 문제 정리
3.3. 언제 extends를 사용해도 좋은가?
3.4. extends 제거하기
3.4.1. 팩토리와 싱글톤
3.4.2. Singleton에서의 스레딩 이슈
3.4.3. Double-Checked Locking(사용하지 말라)
3.4.4. Singleton 죽이기
3.4.5. Abstract Factory 패턴
3.4.6. 패턴 비빔밥
3.4.7. 팩토리를 이용한 동적 생성
3.4.8. Command 패턴과 Strategy 패턴
3.5. 요약
4. 라이프 게임
4.1. 라이프 얻기
4.2. 라이프 구조를 차트로 표현하기
4.3. Clock 서브시스템 : Observer 디자인 패턴
4.3.1. Observer 구현하기 : Publisher 클래스
4.4. Clock 서브시스템 : Visitor 패턴
5. 소형 데이터베이스 구현하기

1. 소프트웨어 설계의 고고학

1.1. 설계 원칙

  • p.1
    • 복싱에서는 스트레이트, 잽, 훅, 이 세가지 펀치를 기반으로 다른 모든 종류의 펀치가 나온다고한다. ~~~ 이러한 기본 자세가 튼튼하다면 그만큼 다른 펀치를 배우는 데도 진입 장벽이 낮아지기 때문이다.
      • 스포츠를 사용해서 비유를 하는건 쉽게 이해는 되는데, 항상 별로 재미없어. - 김준석
      • 다른 종류지만 검도는 내려치기 자세만 천번인가 연습한다고 합니다. 하루에(만화책이었음ㅋㅋ) 그만큼 기본기가 중요하다는 말이겠죠 - 서지혜

1.2. 의존관계

  • p.3
    • 슬프게도 개발자 입장에서는 의사 결정에 참여하여 변경에 대한 요구를 막지 못하는 것이 대부분이다.
      • 요구사항의 변경같은경우 어쩔수 없지만 기술적인 부분이라면 개발자가 가장 힘있지 않나? - 김준석
        • 그건 인도개발자만.. 원래는 의사결정은 가장 많은 정보를 가진 사람이 내려야하는데, 기술에 대한 결정권을 기술과 거리가 먼 관리자등이 내리는 경우가 있다고 합니다(까라면 까 식으로). 이때의 의사결정권자는 모순적 상황에 처해있을 거란 글을 봤는데ㅋㅋ 1. 기술에 대한 지식이 적거나 거의없다. 2. 지식은 없지만 기술에 대한 확고한 입장을 가지고 있다. - 서지혜
        • 힘이라는 건 고객과 경영진에게 있을걸요ㅠㅠㅠㅠ 일개 개발자는 수드라... - 김수경

2. OO와 디자인패턴 기초 다지기

2.1. 패턴 vs 이디엄

  • p.22
    • 이디엄은 일상적으로 사용하게 된 패턴이다.
      • 지난주엔 이 말 때문에 혼란스러웠는데 책에서 다시 보니 왜 혼란스러웠는지 모르겠어요. - 김수경
        • 난 책보고도 이상한 말이라는 생각밖에 안드는군. - 김준석
    • 1980년대 초 C언어가 왕이었을 무렵 상속은 하나의 디자인 패턴이었다.
      • 지금은 이디엄이 되어 누구나 아무 생각 없이 사용하는 상속이 패턴이었다는 사실도 재미있고 C언어가 왕이었다는 표현도 재미있네요. - 김수경
    • 요즘은 상속과 인터페이스 같은 기능이 많은 언어에 내장되어 있다. 이들은 이디엄이 된 것이다.
      • 에 달린 역자주석을 보니 노스 화이트헤드가 "문명이 진보한다는 것은 인간이 의식적인 노력 없이 자동적으로 수행하는 활동이 증가하고 있음을 의미"한다는 지적을 했다고 한다. 이디엄은 과연 좋은것인가? 이디엄이야말로 생각없이 적용하는 패턴이 아닌가? - 서지혜
        • 다양한 사례에 적용해서 적용되기 전보다 높은 효율을 보일 수 있다는 것이 충분히 검증되었기 때문에 이디엄이 되는 것 아닐까요? 물론 모든 것에 100% 적용되는 이디엄이란 존재하지 않겠지만요. - 박성현
          • 무책임한 상속은 오히려 변화의 크기를 증가시키기도 합니다. 이디엄이라고 반드시 옳은것은 아닌듯ㅋㅋ - 서지혜
        • 이디엄은 가치 중립적이지. 이디엄을 생각없이 적용하는 것이 나쁜것이고. - 김수경
          • 오늘 얘기하면서 깨달았다. 이디엄이 패턴보다 더 습관적으로 적용하기가 쉬울테니(패턴을 몰라도 이디엄은 쓸수있음) 역자가 저런말을 쓴건가봐 - 서지혜

2.2. 디자인패턴이란 무엇인가?

  • p.22
    • 먼저 패턴은 발명되는 것이 아니라 발견되는 것이라는 사실을 이해해야만 한다.
      • 패턴이 목적이 아니라 어떤 의도를 구현하기 위해 만든 코드들에서 비슷한 패턴이 발견된다고 한다. - 서지혜
  • p.23
    • 그러므로 패턴은 해결 방법 그 자체라기보다는 해결 방법의 일반 구조라 할 수 있다.
    • 패턴은 어떤 류의 문제를 해결하기 위해 사용되는 일반적인 기술이다.
    • 패턴은 이와 같이 일반적인 해결 방법이기 때문에 한 프로그램에서 다른 프로그램으로 디자인패턴을 복사해 붙여넣는 것은 거의 불가능하다.
    • 그들은 패턴 자체를 패턴을 설명하기 위해 사용한 코드와 혼동하고 있는 것이다.
      • 이 책을 안읽었다면 나도 패턴과 코드를 혼동하는 실수를 했을것같다.. 사람들은 처음 배운것을 진리라 여기는 경향이 있고 비판하기도 사랑하니까. "패턴은 그게아냐!! 이거라고!!" - 서지혜
  • p.24
    • 현실에서는 한 패턴에 참여하고 있는 객체와 클래스가 동시에 다른 패턴에서도 사용되는 경우가 매우 많다.
    • 패턴에 입문한 지 얼마 안 되는 초보자일수록 무언가 멋져 보이는 클래스 다이어그램에 관심을 쏟는데, 더욱 중요한 것은 '패턴의 의도'(혹은 목적)와 '동적인 행동양식'이다.
      • '동적인 행동양식'이 무엇인지 잘 감이 오지 않네요. - 김수경
        • '동적인 행동양식'은 패턴을 통한 목적 달성에 이루기까지 흐름이 어떻게 이루어지는지에 대한것 같아 -김준석
        • 저자가 정적구조가 아닌 동적 행동양식에 신경을 써라라고 말하는거 보니 실행시간에 일어나는 어떤 변화같은데.. - 서지혜
        • 객체들의 상호작용을 동적 행동 양식이라 하는듯 - 서지혜
    • 시원하면서도 안락한 느낌을 주는 방들을 살펴보면 앞으로 '교차 통풍'이라 부를 패턴이 창발한다.
      • 강의실에서 공대 냄새가 나는 이유를 알았습니다. 강의실은 '교차 통풍' 패턴에 속하지 않아요. - 김수경
        • 하긴 시원하면서도 안락하지 않은게 공대 강의실이지 - 김준석
          • 시원하지도 않은데.. 근데 어제 핸드폰 찾으러 교양학관같는데 거기는 더 심하더라..우엑 냄새나는 찜질방이었음 - 서지혜
    • 이 의도를 만족시킨다면 어떤 구조든 이 패턴의 합당한 실체화가 된다.
  • p.25
    • 패턴의 실체화는 디자인이지 코드가 아니며, 하나의 디자인은 여러 가지 합당한 방법으로 구현할 수 있다.
    • 패턴의 실체화 방식은 다양하지만 여러분이 좋아하는 요소만 쏙 뽑아 사용할 수는 없다.
  • p.26
    • 남서쪽 창은 두 개의 패턴 모두에 참여하고 있다는 점에서 흥미롭다.
  • p.27
    • 중요한 것은 구조를 통해서만 패턴을 파악하는 것이 불가능하다는 사실을 이해하는 것이다.
    • 패턴을 찾아내려면 아키텍처의 의도를 포함한 문맥 정보가 필요하다.
    • 생각 없이 패턴을 복사하고 붙여넣는 것은 마음대로 낙서를 한 뒤 멋진 그림을 주장하는 것과 같은 우매한 것이다.
      • 나도 이런적이 있었지 패턴을 쓴다고 다 좋아지는게 아니니까 - 김준석
      • 피카소가 생각난다 - 서지혜
    • 패턴은 디자인으로 실체화 되고 디자인은 구현으로 실체화 된다.
      • 구현은 추상화 시켜 디자인이되고 그것을 추상화시켜서 패턴이된다 - 김준석

2.3. 패턴, 무엇이 좋은가?

  • p.28
    • 즉 패턴을 사용하지 않고 설명하는 것보다 훨씬 짧고 훨씬 명확했다.
  • p.29
    • 패턴은 커뮤니케이션을 극적으로 향상시켜주는 유기적 프레임워크를 제공하며 결국 이것이 디자인의 모든 것이다.
      • 하지만 커뮤니케이션의 당사자들이 모두 패턴을 알고있다는 전제 하에 가능한 일. - 김수경

2.4. 디자인에서 패턴의 역할

  • p.29
    • 패턴은 구현에 대해 생각하기 시작할 때 등장하게 된다.
    • 건축 계획은 모든 축조 새부 사항을 설명하지는 않는다. 즉 어디에 벽이 있어야 할지를 보여줄 뿐 벽을 어떨게 만들어야 하는지에 대해 설명하지는 않는 것이다.
  • p.30
    • 디자인 패턴은 보통 디자인 문서에 상세히 나타나지는 않으며 구현하는 사람이 내리는 결정을 나타내 준다.
    • 구현은 스스로 말할 뿐이다.

2.4.1. 패턴과 단순함 사이의 긴장

  • p.30
    • '우둔한 프로그래머와 아키텍처'는 패턴이 항상 좋은 것이며 가능한 모든 곳에서 사용해야 한다고 일관되게 믿는다.
  • p.31
    • 프로그래머들은 미래에 등장할지도 모를 요구 사항까지도 추가하는 경향이 있다.
    • 미래에 변화될 것이라 생각하기 때문에 코드를 복잡하게 하는 것은 좋은 생각이 아니다.(적어도 내 경우는 미래를 예측하려 할때마다 내 예상이 빗나갔다.)
    • 요구되는 기능을 삭제하는 것은 불필요한 기능을 추가하는 것만큼 나쁘다.
      • 요구되는 기능을 왜 삭제하는가? 요구되는 기능을 구현하는게 우리 일 아닌가? -임상현
        • 요구 기능을 구현하는게 어렵다며 맘대로 다른거 붙이는 사람도있음.. 예를들면 파일을 삭제할때 복구기능을 만들기 싫어서 확인 다이얼로그를 띄우지.. - 서지혜
          • 그리고는 구현하고 나서는 스스로 납득을 하게 됩니다. '이러이러하게 하는게 더 좋은 사용자 경험을 제공할 수 있을거야.' 는 무슨 -_-; - 박성현
        • 구현은 복잡한데 돈을 조금 준다면 삭제해버리겠지. - 김수경
    • 프로그래머는 지금 앞으로 어떻게 될지 모를 기능을 추가하는 것이 아니라 새로운 기능을 추가하거나 기존의 것을 수정하기 쉽도록 프로그램을 작성해야 하는 것이다.
    • 우리는 필요로 하는 바로 그것을 해야한다.
    • 사용자가 무언가를 정말로 하고 싶어한다면 이에 대해 질문하지 말아야 한다고 주장한다.
      • 확실히 근근히 나오는 확인 팝업창 겁나 귀찮습니다. -임상현
      • 실수했다 생각되면 되돌릴 수 있도록 만들어 줘라. 그래서 휴지통은 편하지. 절대 영구삭제 하면 안돼 - 서지혜
  • p.32
    • 단순함 , 완전성 그리고 수정의 용이성이란 세가지 요구 사항은 상충되기도 한다.
    • 인터페이스는 패턴 전체를 도입하는 것과는 달리 그다지 복잡성을 증가시키지 않는다. 반면 기능 변경이나 추가 시 리팩토링이 쉬워진다.

2.5. 패턴 분류하기

  • p.32
    • 패턴을 분류하는 것은 필요한 상황에서 적절한 패턴을 선택하는 것을 용이하게 해준다는 점에서 유용하다.
  • p.34
    • 패턴들이 서로 의존하고 있다는 사실을 이해하는 것도 중요하다.
    • 여러 패턴들이 서로 관련이 있으며 실제 프로그래밍할 때는 이들을 엮어 함께 사용하는 경우가 많다는 사실만 명심하면 된다.
  • p.34
    • 패턴 간의 연관성 의존성 때문에 한 패턴을 다른 패턴과 구분하기 어려울 수도 있다. 이럴 경우에는 정적 구조 대신 패턴의 의도에 초점을 맞추기 바란다.

2.5.1. 디자인 일반

  • p.35
    • 객체 지향 디자인(OOD)과 객체 지향 프로그래밍(OOP)은 매우 다른것이다.
    • 디자인 프로세스는 유스케이스 분석등을 통한 요수사항 수집에서 시작해 코딩이 시작되는 디자인으로 끝나게 된다.
    • 프로그래밍 프로세스는 디자인에서 시작하며 상속, 캡슐화, 디자인 패턴 등을 이용하고 디자은의 실체인 컴퓨터 프로그램을 내놓는다.
    • 이와같은 기술의 융합은 애자일(Agile) 방법론에서 특히 중요한데 디자인과 코딩이 병렬적으로 진행되기 때문이다.
      • 애자일을 하려면 디자인, 코딩을 둘다 할줄 알아야 하나.. - 서지혜
    • 어떤 애자일 방법론도 춤추는 꼭두각시 프로그래머와 이를 조종하는 아키텍트란 도식을 지지하지 않는다.
      • YES맨이 되지 말아라는 건가? - 서지혜
        • 프로그래머도 아키텍쳐를 이해해야한다는 것 아닐까? - 김수경
          • 아하, 자기가 어디의 뭐를 하는지는 알아야 한다는 뜻? - 서지혜

2.5.2. 자바를 C언어 스타일로 프로그래밍하기

  • p.37
    • 절차 지향 프로그래밍은 데이터를 조작 혹은 검토하는 서브루틴 간의 데이터 흐름을 구조화 한다.
    • 사실 많은 절차 지향적 프로그램은 사용자 인터페이스를 통해 데이터베이스 테이블을 보여주는 역할을 할 뿐이다.
    • 객체 지향 시스템은 상호 협동하는 에이전트들의 네트워크이며, 에이전트는 메시지를 통해 통신한다.
    • 객체 지향 시스템과 절차 지향 시스템을 구분하는 한가지 좋은 방법은 무언가를 변화시킬 때 어떤일이 발생하는가를 보는 것이다.
      • 설계할 때 이것을 미리 상상해보면 도움이 되는 것 같아요. 과연 내가 이렇게 짜면 이런 변경이 생길 때 어떻게 될까? - 김수경
    • 절차 지향 시스템에서는 변화가 프로그램의 나머지에 '퍼져나가는'경향이 있다.
    • 객체 지향 시스템에서는 변화가 한곳에 집중되는 경향이 있다.
  • p.39
    • 내가 MFC가 상당 부분 객체 자향적이지 않다는 이야기를 하자 그의 대답은 자신도 알고 있다는 것 이었다.
      • 내가 MFC가 객체 지향적이지 않다고 말했을때 상대는 MFC야말로 객체지향적이다 라고 했던 것 같다. - 서지혜
  • p.40
    • 절차 지향적 해결 방법이 본질적으로 나쁜 것은 아니다. 하지만 선택을 할 때는 이 선택에 따르는 위험까지 고려해 보기 바란다.

2.5.3. 열린 눈으로 프로그래밍하기

  • p.40
    • 디자인은 선택과 트레이드 오프, 리스크 관리의 연속이다.
      • 어떤 디자은을 선택할 때는 선택으로 인한 장단점을 고려(트레이드 오프)해야 한다. 그리고 그것을 취한뒤에는 그로인해 잃은 것을 감내해야한다(리스크 관리) 이게 맞나? - 서지혜
    • 자신이 하고 있는 일이 어떤 결과를 초래할지를 알지 못한다면 이는 디자인을 하고 있는 것이 아니라 어둠 속에서 비틀거리리고 있을 뿐이다.
      • 디자인이 아닌 구현단계에서도 이러한 상황을 "우연에 의한 프로그래밍"이라고 설명을 하더라고요. 그리고 대부분의 개발자는 "우연에 의한 프로그래밍"을 하고 있다고... 실용주의 프로그래머에서 본 기억이 있네요..? - 박성현
        • faith coding과도 상통하는 말인가ㅋㅋ - 서지혜
  • p.41
    • 어떤 언어의 기능 혹은 이디엄이 초래할 수 있는 폐해를 이해하면 해당 기능과 이디엄을 사용하는 것이 적절한지 아닌지 좀 더 현명하게 결정할 수 있다.

2.6. 객체란 무엇인가?

2.6.1. 허튼소리!

  • p.42
  • 우선 OO 시스템을 지능 있는 동물(객체)의 모임이라 생각하자.
  • OO 디자인에서 가장 중요한 원리는 데이터 추상화이다.
  • "객체는 메소드라 불리는 함수가 있는 자료 구조이며 메소드가 자료 구조를 조작한다."라는 설명을 보았을지도 모르겠다. 허튼소리! 당치 않다.
    • 봉봉 생각나! 봉봉도 그책을 읽은게 아닐까?- 김준석
    • 나도 객체지향은 어떤 작업에 대한 데이터와 메소드를 객체가 가지고 있는 것이라고 생각했음!! - 서지혜
    • 이러한 착각은 흔히 C를 배우고 C++을 배울 때, '객체'가 아닌 문법 클래스'를 쉽게 설명하려고 "클래스는 structure(data) + method(to do) 이다." 라는 요상한 설명을 접하게 되면 하게 되는 것 같습니다. 처음에 이런 설명을 접하게 되면 나중에는 생각을 바꾸기 어려워지죠 (아니 귀찮아지는 건가...) -_-;; - 박성현
      • 정답. 클래스는 구조체+메소드에요 라는 설명을 열혈강의 c++에서 본듯..? - 서지혜
    • 2학년땐 나도 저렇게 생각했다ㅜㅜㅜ Spring/탐험스터디에서도 얘기했지만 그래서 객체지향설계라면 메소드만 있는 클래스는 존재해선 안된다고 말한 적도 있음ㅜㅜㅜㅜ 부끄럽다... - 김수경

2.6.2. 객체는 기능의 집합이다

  • p.43
    • OO의 제 1 지령.
      객체에 어떤 작업을 하는 데 필요한 정보를 요청하지 말라. 대신 작업을 하는 데 필요한 데이터를 갖고 있는 객체에 일을 해달라고 요청하라.
    • 켄 아놀드는 다음과 같이 말한다. "정보가 아닌 도움을 요청하라(Ask for help, not for information)."
      • 이건 굉장한 개념이야!!! 너! 일해! -김준석
      • 도움을 요청하라는 말을 보니 만객체(-_-;;)는 평등하다는 말이 생각나는군 - 서지혜
    • 중요한 것은 원리이지 사용하고 있는 언어가 아니다.
      • 자바가 객체지향 프로그램을 줄거라 생각하지마!! - 서지혜
      • 이건 6피의 중심에서 외치고 싶은 말. 많은 후배들이 이런 질문을 한다. C로는 객체지향 못하는거 아니에여? ;;;;;;; 혹은 OOP로 짜고있어요 ㅋ해서 보면 자바로 짠다는 것 외엔 도대체 객체지향의 원리가 어디에 녹아있는지 알 수 없는 코드라거나... 클래스 쓰면 다 OO냐ㅜㅜ 그렇게 간단하면 학교에서 왜 한학기나 할애해서 배우겠어. - 김수경
        • 한학기를 할애해도 못 가르치고 못배우니 저렇게 쓰겠지 - 서지혜

2.6.3. 어떻게 잘못하고 있는가?

  • p.45
    • OO는 컴퓨터 프로그램에 내재하는 피할 수 없는 복잡성을 조직화 하는 것이지, 복잡성 자체를 제거하는 것이 아니다.
    • 이러한 룰을 따르면 문제점을 고치거나 새로운 기능을 추가함으로써 발생하는 변화가 한곳에 집중된다. 이때 유지 보수가 용이하다는 것과 복잡하지 않다는 것을 혼동하지 말기 바란다.
  • p.48
    • 잘못된 마인드를 가진 프로그래머는 모든 언어를 이용해서 쓰레기 코드를 작성해 내는 마법을 부릴 수 있다.

2.6.4. 어떻게 '올바르게' 할 수 있는가?

  • p.48
    • 리라(lira)를 통화로 사용하던 이탈리아가 유럽의 단일 통화인 유로(euro)를 사용하게 되면서 겪었던 고통을 상상해 보자
      • 무슨일이 있었지?? 궁금하다 - 서지혜
    • 만약 빌 게이츠가 은행에 걸어들어와 계좌를 개설한 뒤 그의 모든 재산을 예금하겠다고 하면 어떻게 될까? 여러분이 은행 지점장이라면 절대 빌이란 고객을 놓치고 싶지 않을 것이다.
      • 역시 빌게이. 돈의 힘이란. -김준석

2.7. 셀룰러 오토마타


  • p.52
    • 셀룰러 오토마타(Cellular automata)의 프로그램 구현은 OO 시스템의 훌륭한 예가 된다. 셀룰러 오토마타 프로그램은 복잡한 문제를 정확히 객체 지향적인 방식으로 해결한다.
      • 이런 흐름을 만들수 있어야하는데.. - 김준석
    • 교통 흐름을 예측하는 것은 카오스 이론이 해결하려는 유명한 문제이며,, 그 해결은 매우 어렵다. 이때 시뮬레이션 모델의 행위에 기반하여 예측할 수 있다는 가정을 한다면 교통 흐름을 모델링, 시뮬레이션하는것이 유용할 것이다.
      • SimCity!!!! - 김준석
      • 스터디 하다말고 심시티에 빠진 김준석씨... - 서지혜

  • p.54
    • 모든 OO 시스템과 마찬가지로 이러한 종류의 룰은 주변 코드에 영향을 미치지 않으면서도 바뀔수 있다.

  • p.55
    • 어떤 객체는 자신이 포함하고 있는 객체에 해당 객체가 필요로 하는 외부 정보를 넘겨줌으로써 문제를 해결한다. 즉 위임을 통해 문제를 해결한다. 메시지가 위임하는 객체로 전달되어 갈수록 추가적인 인자를 포함하는 경향이 있다.
    • 좋은 클래스는 getter와 setter메소드를 갖지 않는데, 이런 메소드는 구현 상세를 노출시키기 때문에 결과적으로 유지 보수를 어렵게 만들기 때문이다. 예를 들어 getter 메소드의 리턴 타입이 바뀌게 되면 getter를 정의하는 객체뿐 아니라 'getter'를 호출하는 모든 코드 또한 바꾸어 주어야 한다. 잠시 후에 getter와 setter 메소드 없이 시스템을 디자인하는 방법에 대해 설명할 것이다. 기대해도 좋다.

  • p.56
    • 보라고! 차들이 도시 안을 돌아다니잖아!!

2.8. 접근 메소드와 수정 메소드는 나쁘다


  • p.57
    • 이 말이 메소드가 값을 반화하면 안 된다거나 'get'혹은 'set'기능이 언제나 부적절하다는 것은 아니다. 객체는 때때로 시스템 전반을 흘러다니며 작업을 수행하도록 도와주어야 한다. 하지만 많은 경우 get/set 메소드는 private 필드를 접근하는 용도로만 부적절하게 사용되며, 이런 사용이 많은 문제를 발생시킨다.
  • p.58
    • 유지 보수성의 최대 적 중 하나인 중복 코드를 작성해야 한다.

  • p.60
    • 이미 데이터를 갖고 있는 객체가 일을 하게 하는것은 어떨까? 다시 말해 신의 클래스에서 접근 메소드를 통해 가져온 데이터를 갖고 어떤 작업을 하는 코드를 이 데이터를 저장하고 있는 객체로 옮기면 어떨까? 접근 메소드는 사라지고 코드는 단순해진다.
    • 아무 생각 없이 접근 메소드와 수정 메소드를 사용하는 것은 public 필드를 사용하는 것이 위험한 것과 같은 이유로 똑같이 위험하다.
      • 생각해보니 get, set이랑 public이랑 다를게없다.. - 서지혜
  • 구현은닉이라는 원리는 객체 지향 시스템의 품질을 평가하는 좋은 지표가 된다. 클래스의 구현을 마음대로 바꾸어도, 심지어 기존 클래스를 버리고 새로운 클래스를 작성하더라도 이를 사용하는 객체의 코드에는 영향을 미치지 않을 수 있는가?
  • 만약 구현 은닉을 하지 않는다면 다른 OO기능을 사용하는 것이 큰 의미가 없게된다.

  • p 62
    • 이러한 '추측에 의한 디자인하기'전략은 사용하지도 않는 메소드를 작성하는데, 즉 필요치 않은 기능을 클래스에 추가하는 데 불필요한 시간을 낭비하게 한다.
      • 음? 디자이너들의 상상 디자인인가? - 서지혜

2.8.1. 스스로를 표현하라


  • p.62
    • 내가 실제로는 비지니스 로직에 어떤 UI 코드로 삽입하지 않았다는 사실을 기억하기 바란다.

2.8.2. 자바빈즈와 스트럿츠


  • p63
    • 불행히도 아무도 이러한 getter/setter를 이런 의도대로 사용하지 않았다.

2.8.3. 리팩토링


  • p65
    • 이클립스는 현재 프로젝트의 범위에서만 리팩토링해 준다.
    • 두번째로, 자동화된 리팩토링은 단순한 작업에는 매우 휼륭하게 동작하지만 큰 변화에는 그렇지 못하다.
    • 코드가 올바른 방식으로 구조화되지 않았기 때문에 유지 보수가 필요 이상으로 어렵다는 것이다. 이런 경우 리팩토링이 아닌 프로그램의 재디자인이 필요하다.

2.8.4. get/set 없는 삶

  • p 67
    • CRC카드를 통한 첫 번째 시도는 '어림 잡기'일 뿐이다.
  • p68
    • 어떤 사람들은 이러한 방식으로 CRC카드를 이용해 실제 프로그램까지도 디자인하지만 이 방식은 복잡한 대규모 프로그램까지 수용할 정도로 효율적이지는 않다. 대부분의 프로그래머는 정식 프로세스를 사용하여 UML로 동적 모델과 정적 모델을 개발한다.
    • 모델링은 내가 마지막 경험 법칙에서 언급했듯이 가능한 '문제 도메인'안에 머물러 있어야 한다. 하지만 많은 개발자들이 자신은 문제 도메인을 모델링하고 있다고 생각하지만 실제로는 구현 레벨에서 모델링을 한다.

2.8.5. 언제 getter와 setter를 사용해도 괜찮은가?


  • p69
    • 데이터를 '꺼내는(pull)'것보다는 '넣는(push)'것이 보다 좋다.
    • '어떤 용도로 사용될지를 모두 예측할 수 없어'와 같은 문제는 자바 패키지 전반에 퍼져 있다. 이런 경우 이미 말했듯이 객체에서 모든 getter와 setter를 제거할 수 없다.

2.8.6. getter/setter 이슈 정리


3. 인터페이스로 프로그래밍하기 그리고 몇 개의 생성 패턴

  • 75p
    • 인터페이스 관점에서 프로그래밍 하는 것은 OO 시스템의 기본 개념이며 GoF와 디자인 패턴은 이의 구체적이 예가 된다.
    • 하지만 많은 자바 프로그래머들은 인터페이스를 거의 사용하지 않고 extends 관계를 남용하고 있다.

3.1. 왜 Extends가 나쁜가?

  • 75p
    • extends 키워드는 나쁘다.
    • ... 명성 있는 디자이너라면 가능한 사용을 자제할 정도로는 충분히 나쁘다.
    • ... 혹시라도 내가 extends를 절대 사용하면 안 된다고 주장하고 있다고 생각하지는 말기 바란다.
      • 아저씨 많이 까임의 증거 -김준석

    • 디자인 패턴은 크게 보면 구현 상속(extends)을 인터페이스 상속(implements)으로 바꾸는 방법을 설명하고 있다.

  • 76p
    • "많은 사람들이 '우리 회사의 제품은 C++을 이용해 만들었기 때문에 객체 지향적입니다' 라고 설명했다는 CEO에 대한 이야기를 한다. 그런데 이 중 어떤 이들은 이 이야기가 농담이란 사실을 모르고 있다.
      • 재미있네요. 나는 mfc는 객체 지향적이다 라는 말과 알수없는 클래스들을 만들어 놓고 객체지향이라고 한 말을 들은적이 있습니다. - 서지혜
    • 자바 프로그래머들은 종종 extends와 같은 언어의 기능을 객체 지향 자체와 혼동하곤 한다.
    • 다형성이란 개념은 OO의 고유한 특성이며, 다형성을 사용하지 않는 프로그램은 객체 지향적이지 않다는 주장은 설득력있다.
    • OO 시스템에서는 데이터 캡슐화가 선택이 아닌 필수이다.

  • 77p
    • extends와 implements 간의 유사성은 C++ 언어에서는 명확하다. C++는 이 둘을 구분하지 않기 때문이다.
      • C++을 배우고 자바를 배우면 익숙한 구현 상속을 많이 사용하게 되지. C++에도 인터페이스의 개념이 있지만 시작부터 구체 클래스를 만드는 습관때문에 거의 쓰지 않았었다. - 서지혜

3.2. 인터페이스 vs. 클래스

3.2.1. 유연성의 상실

  • 77p
    • 구현 상속이 도대체 왜 나쁠까? 명시적으로 구체 클래스의 이름을 사용하면 특정 구현에 종속되는데 이는 결과적으로 수정을 필요 이상으로 어렵게 만든다.

  • 78p
    • 애자일 방법론이 모든 프로젝트에 들어맞는 것은 아니지만, 개발 기간 동안 요구 사항의 변화가 있는 중소 규모 프로젝트에는 매우 효과적이다.
      • 중소규모 말고 대규모 프로젝트는 어떨까...? - 김준석

    • 애자일 병행 개발의 중심에는 유연성이란 개념이 있다. 새로 추가된 요구 사항을 쉽게 반영할 수 있는 코드를 만든다는 것이다. 또한 아마도 필요할지도 모르는 기능을 구현하기보다는 꼭 필요한 기능을 구현하되, 프로그램은 변화를 수용할 수 있어야 한다.
      • 애자일이란 민첩하게 대응한다는 뜻이다. 이런 의미에서 애자일이 변화를 수용할 수 있는 객체 지향을 사용하는 것이 당연한듯하다. - 서지혜
    • ... 변화는 이런 식으로 파급된다.

3.2.2. 결합도

  • 80p
    • 예를 들면 상수가 아닌 모든 필드는 항상 private이어야 한다. 정말? 예외는 없다. 절대로!
    • protected 인스턴스 변수는 정말 역겹다. protected 변수는 public을 의미하는 다른 방법일 뿐이다.
      • 나는 구현 상속을 사용할 때 get/set을 만드는 것도 귀찮아 protected를 썼었는데, 마치 나에게 하는 말 같군. 기분이 안좋아진다... - 서지혜
  • p81
    • 나는 개발을 하면서 OO 원칙 적용의 '엄격성(strictness)'과 코드를 빨리 작성하고 유지 보수하기 좋은 코드를 작성하는 것 사이에 높은 상관관계가 있다는 사실을 깨달았다.
      • 어느정도 의심가는 부분이 있는경우는 꼭 고쳐야되게되더군 - 김준석
      • 코딩하다가 어느 순간, 이거 좀 잘못하고 있는거같은데.. 하는 순간이있다. 그걸 애써 무시하고 넘어갔는데 토이 수준이 아니라면 큰 문제였겠지.. - 서지혜

3.2.3. 깨지기 쉬운 기반 클래스 문제

  • p81
    • 기반 클래스는 기반 클래스만을 따로 떨어뜨려 놓고 안전하게 수정할 수 없으며, 모든 파생 클래스를 함께 살펴보고 테스트해 보아야 한다.
      • 슈퍼 클래스를 수정하면 알수없는 새끼 에러들이 창발한다ㅋㅋㅋ - 서지혜
  • p86
    • 구현 상속을 사용하면 기반 클래스를 수정할 때마다 파생 클래스들이 제대로 작동하는지를 테스트해야 한다.
  • p87
    • 기반 클래스를 수정할 때마다 파생 클래스를 검토해 보아야 한다면 이는 기반 클래스를 확장하고 있는 것이 아니라 인터페이스를 구현하고 있는 것이다.
      • 그러고보니 일일이 오버라이딩할 바에는 인터페이스를 implements하는게 더 나을거같네? - 서지혜

3.2.4. 다중 상속

  • p90
    • 구현 상속이 '나쁘다면' 분명 다중 구현 상속은 더 나쁘다.


3.2.5. 프레임워크

  • p91
    • 깨지기 쉬운 기반 클래스 문제를 프레임워크 기반 프로그래밍에 대한 언급 없이 마칠 수는 없다. MFC(Microsoft's Foundation Class) 라이브러리와 같은 프레임워크는 클래스 라이브러리를 만드는 인기있는 방법이 되었다.
      • 나는 처음부터 MFC가 별로 마음에 안들었다. 기능을 하나 구현하려면 이곳저곳을 손대야 해서.. - 서지혜
    • 마이크로소프트의 문제 해결 방식이 항상 올바른 것은 아니다.
      • 수경이가 읽어주었던 MS사의 직원들이 말하는건 도움이 안된다는게 기억나는군. - 김준석
        • 개떡같은 UI랑은 다른 문제인거같은데요ㅋㅋㅋ 마소가 자주 까이는건 그만큼 영향력이 크다는 말일듯 - 서지혜
          • 그 책은 UI에 대해서 말해주는거였나? 난또 전체적인 거라고. 마소가 영향력이 크긴하지 - 김준석
  • p92
    • 구현 상속 기반 아키텍처는 깨지기 쉬운 기반 클래스 문제 외에도 너무 많은 클래스를 구현해 주어야 하는 문제를 갖고있다.

3.2.6. Template method와 Factory Method 패턴

  • p99
    • Factory Method 패턴은 좋은 선택이 아니었다. 이번 장의 뒤에서 살펴볼 Strategy 패턴 등은 Factory Method 패턴의 멋진 대안이 된다.
    • 즉 아무도 필요하다고 요구하지 않은 부분까지 유연하다. 이와 같은 복잡도를 필요로 하는 시스템이 실제로 있을지는 모르겠지만, 스윙을 사용하다 보면 "왜 이정도의 유연성이 필요할까?" 라는 생각을 자주하게 되며, 또한 과도한 유연성으로 인한 복잡함이 별 이점 없이 개발 기간을 길게 만든다.

3.2.7. 깨지기 쉬운 기반 클래스 문제 정리

  • p101
    • 여러분은 '꼼수'에 대한 생각할 필요가 없는 코드를 작성해야 하기 때문이다.
    • 프로그램을 정상적으로 동작하게 할 수 있는 꼼수를 발견했다면 뭐 그런대로 괜찮다. 하지만 내 주장의 핵심은 애초에 상속으로 인한 문제가 발생하지 않도록 했어야 한다는 것이다.
  • p103
    • 모든 선택에는 트레이드 오프가 있으며 해당 방법과 이를 대체할 수 있는 방법의 장점과 단점을 잘 헤아려 조율해야 할것이다.

3.3. 언제 extends를 사용해도 좋은가?


  • p103
    • 이제 언제 extends 관계를 사용해도 좋을지 논의해 보도록 하자.
    • 우선 클래스 정규화(데이터베이스 디자인에서 빌려온 용어이다)를 할 때 유용하게 사용할 수 있다.
      • 그렇군. 정규화 계층구조는 위에 있는 코드를 아래에서 써서 만드는거니까 상속을 이용하는게 편하다는거군? 예제 없나 근데? - 김준석

    • 디자인을 하는 데 어떤 방법을 따르느냐는 결과에 큰 영향을 미친다.

  • p104
    • 올바른 OO디자인은 다음과 같은 과정을 밟는다.
      • 여기 5개가 있는데 이것을 외워야 하는가!? - 김준석

    • 동적 모델링으로부터 클래스 다이어그램을 도출하라. 이렇게 하면 실제 필요한 연산과 관계만이 포함되기 때문에 정적 모델이 현실적이 되고 가벼워진다.
      • 형진이가 지도해준 동적 모델링으로 우리가 하고있던 DB와 임상이 하는 SE를 모델링했을때는 참 재밌었지. 확실히. 내가 짠 프로그램보단 복잡도가 낮아보였어. 부럽. - 김준석

    • p105
      • 'is-a'는 그리 훌륭한 디자인 도구가 아니다. 우리가 늘 사용하는 자연어에 휘둘리지 말자.
        • 클래스 상속 기반 계층구조일때는 유용할듯 하지만. 우리가 원하는 extends를 제거하는 동적 디자인 시에는 그리 유용한 도구가 아닌것 같다. 'is-a'가 얼마나 날 잘못된 길로 이끌었던가! - 김준석

      • 단순한 클래스 계층 구조는 복잡한 계층 구조보다 만들고 유지 보수하기 쉽다. 또한 인터페이스를 이용하여 구현 상속이 하는 것과 같은 작업을 수행할 수도 있다.
        • 음.. 확실히 이 책은 구현상속의 장점에대해 충분히 알아들어야지 extends의 장점에 대해 이해할수 있을것 같다. 이런경우가 어떤때인지 모르니까 - 김준석

      • 상속한 메소드에서 예외를 던지지 말라. 즉 리스코프 대체 원칙(LSP)를 지키라. LSP를 어기면 다형성을 이용한 코딩을 할 수 없고, 결과적으로 개방 폐쇄의 원칙(OCP)도 지킬 수 없게 된다.

3.4. extends 제거하기


  • p107
    • 여러분이 시스템을 리팩토링하고 있다 가정해 보자. 차근차근 시작해보자.
      • 천리길도 한걸음부터. 이 부분이 2장의 알짜배기 같은데. 정말 길다. 그리고 재밌다. - 김준석


~~java
interface Employee
{   void youAreFired();
}
  • 직원은 항상 해고될 준비를 해야한다. - 김준석

3.4.1. 팩토리와 싱글톤


  • p108
    • 많은 패턴들이 구현 시 Abstract Factory에 의존 하는 경우가 많기 때문에 Abstract Factory는 일종의 빌딩 블록이 되는 패턴이라 할 수 있다.
      • Abstract Factory는 다른이들에게 널리 잘 알려져(?) 쓰이는 유용한 패턴인가보다 - 김준석

    • Abstract Factory의 모든 실체화에서 공통되는 주제는 팩토리를 사용하여 정확한 타입을 모르는 객체를 생성한다는 것이다.

  • p110

~~java
public static class EmployeeFactory
{   private Factory(){/*비어있다/}

    public static Employee create()
    {   return new Employee()
        {   public void youAreFired(){/*많은코드*/}
        }
    }
}
  • peon 이런거 없이 그냥 내부 클래스를 Employee()를 implement시킨걸로 반환시켜버리는군. 이름조차 없으니 private Peon으로 만든것보다 심한데? 정말 상상도 못할 클래스임 - 김준석


  • p111
    • 유일성'과 전역 접근'이란 조건을 만족시키면 Singleton 패턴의 실체화라 할 수 있다. Employee factory는 두 조건을 모두 만족시키므로 합당한 Singleton 패턴 실체화이다.
      • 전역접근 이런게 많으면 관리하기 힘들다는거 아녀? - 김준석

3.4.2. Singleton에서의 스레딩 이슈


  • p113
    • 모든 것을 static으로 하는 전략은 단순하고 멋지지만 많은 경우 사용할 수 없다.
  • p114

~~java
class Singleton
{  private static Singleton instance = null;
   public static instance()
   {  if( instance == null)
      { instance = new Singleton();
      }
      return instance;
   }
   //...
}
  • Java에서 GUI등 클래스 자동 생성 툴을 사용하면 대부분 저 모양을 이용해서 나온다. 근데 정말 많으면 보기 짜증난다. -김준석

3.4.3. Double-Checked Locking(사용하지 말라)


  • p116
    • DCL을 없애는 일은 바퀴벌레를 박멸하는 일에 비유되곤 한다. 10마리를 죽이면 하수구에서 1000마리가 기어 나온다.
      • .... 바퀴벌레라니. 이거 사람한테 비유한거임? - 김준석

    • 이 주제에 대해 글을 쓸 때마다 DCL 문제를 해결했다고 생각하는 '매우 똑똑한'프로그래머들로 부터 수십 통의 메일을 받았다. 그들은 모두 틀렸으며 어떠한 꼼수도 제대로 동작하지 않는다. 더 이상 내게 메일을 보내지 말기를 바란다.
      • 단골주제. 얼마나 많이 싸운거야? - 김준석

3.4.4. Singleton 죽이기


  • p117
    • 멋지게 커넥션을 닫는 방법은 없을까?
      • 탭댄스를 추고 물구나무서서 왼손을 들어 코끼리를 들어올린뒤 닫으면 멋질듯 - 김준석

  • p118
    • 종료자에 대한 나의 일반적인 조언은 '사용하지 말라' 이다.
      • 그리고 멋지게 닫은게 하지 말라는 것임 - 김준석

  • p119
    • 또한 셧다운 훅 안에서 Singleton을 사용한다면 죽었다 되살아나는 좀비 Singleton을 만들 위험도 있다.
      • 그리고 좀비가 너의 뇌를 먹겠지(Zombie ate your brain) - 김준석

3.4.5. Abstract Factory 패턴

  • p120
    • 앞에서 객체를 생성할 때 Singleton 패턴과 Abstract Factory 패턴이 자주 함께 사용된다고 설명했다. 그러므로 Abstract Factory에 대해 좀 더 알아보기로 하자.

    • 결과적으로 프로그래머는 외부 코드에 영향을 미치지 않으면서 구체 Peon 클래스를 마음대로, 심지어 그 이름조차도 바꿀 수 있다.
      • 근데 이름이 없으면 어떻게 죽이나? youAreFired()같은 자살을 만들어놔야하나? garbage Collector를 이용해야하나? -김준석

  • p121
    • Abstract Factory 패턴은 관련된 일련의 클래스 '군(family)'중 하나를 생성한다.

  • p122
    • Abstract Factory 패턴의 주요 장점은 격리(isolation)이며, 인터페이스를 통해 객체 생성을 가능 하도록 해준다.

  • p123
    • 이름이 있는 클래스 대신 익명의 내부 클래스를 사용하여 코드를 단순화시켰다(단순함은 언제나 좋다)
      • 난 정말 진짜 단순한거 좋아해. 근데 이거 여러개를 만들면..? 이름 안줘도 되는거 맞는겨? - 김준석

  • p124
    • 자바가 인터페이스에서 static 메소드를 지원했다면 좋았겟지만 현재는 그렇지 않다.
      • 과거에도 그랬고 현재까지 그렇지 않다는거지? 미래에는 저자가 말하는 이디엄이 되었으면 좋겠군 - 김준석

  • 패턴은 여러 방식으로 실체화할 수 있다. 중요한 것은 문맥과 의도이지 정적 구조가 아니다.

3.4.6. 패턴 비빔밥


  • p124
    • '관점을 바꾸면 보이는 것이 다르다'는 것을 보여주는 자바의 흥미로운 예를 하나 더 살펴보자.

  • p125
    • 관점을 바꾸어 보면 URLConnection은 InputStream 구현체들을 생성하는 Abstract Factroy이기도 하다.

  • p126
    • 이 예제의 핵심은 관점의 전환에 익숙해지자는 것이다.

3.4.7. 팩토리를 이용한 동적 생성


  • p128
    • 하드 코딩을 통해 어떤 객체를 생성할지를 결정하게 되면 프로그램이 실행되고 잇는 도중에는 행위를 바꾸지 못한다.
      • 첨에 하드 코딩을 봤을때. Hard지에 쓰는 손코딩을 생각했었다. 나만그런가? - 김준석

  • p128
    • 그리고 Class.forName()을 이용하여 앞에서 만든 이름에 해당하는 Class 객체를 생성하게 된다.
      • 진짜.. 자바에 대해 나는 아직 반도 모르는듯 하다. - 김준석

3.4.8. Command 패턴과 Strategy 패턴


  • p131
    • 객체를 추상적인 방법으로 생성하는 데 유용한 다른 패턴은 Strategy 패턴이다. 그리고 Strategy 패턴은 좀 더 일반적인 패턴인 Command 패턴의 특별한 경우라 할 수 있다.
    • C혹은 C++에서는 알고리즘을 구현하는 함수를 작성한 후 함수 포인터를 넘겨주는 방식으로 알고리즘을 전달할 수 있다.
      • 아.. 함수 포인터. 좀 신기했었음. Java에선 C에서보다는 많이 이 패턴들이 이디엄에 가까워진듯. - 김준석

    • 자바 스레드는 전형적인 Command패턴의 구현체이다.

  • p132
    • Strategy 패턴은 특정 연산을 '어떻게' 수행할 것인지에 대한 전략을 캡슐화한 Strategy 객체를 전달한다.

  • p135
    • 사실 거의 대부분의 상황에서 Strategy는 Factory Method의 좋은 대안이 된다.

3.5. 요약



4. 라이프 게임


  • p139
    • 아마도 라이프 게임은 지구상에서 가장 많이 구현된 애플리케이션 중 하나일 것이다.
      • 이 Life Game말고 Life Game 류를 뜻하는거겟지? - 김준석

    • 10개의 디자인 패턴을 실제 프로젝트에서 사용하는 것처럼 함께 사용해 볼것이다. 다행히 프로그램이 이해하지 못할 정도로 거대하지는 않다. 클래스와 인터페이스를 모두 합쳐 20개 밖에 되지 않는다.
      • ... 음.. 20개. GUI쓰면 그정도 나오긴 할것같아. - 김준석

    • 나의 라이프 구현은 자바 클라이언트 측 GUI 라이브러리(스윙)을 사용하며, 여러분이 스윙의 기본적인 기능은 알고 있다고 가정한다.
      • '레벨이 낮아 해당 지역에 진입할수 없습니다.','퀘스트를 수행하는데 필요한 아이템을 가지고 있지 않습니다'를 머리에 띄우지 않을수 있어서 좋군. - 김준석

    • 이번장에는 많은 코드가 나온다.

    • 나는 종종 전체 코드를 보여주지 않는 책들 때문에 좌절하곤 했다.

    • 마지막으로 이번 자의 코드는 최선의 라이프 게임 구현은 아니다.

4.1. 라이프 얻기

  • p140
    • 라이프는 1장에서 논의한 것과 같은 간단한 셀룰러 오토마타이다.

    • 인류학자인 내 친구는 라이프 게임에서 발견되는 패턴이 인간 사회에서 발견되는 행동 패턴을 연상시킨다는 이야기를 했다.
      • 어떻게 만났을까 궁금하다. - 김준석

    • 전체의 행동은 정말이지 흥미롭다.

  • p141
    • 이러한 과정은 영원히 계속된다.
  • p143
    • 서울대 컴퓨터 공학부의 문병로 교수는 어떤 사람의 창조성은 어려서부터 그 사람이 쌓아 놓은 사고 빌딩 블록의 질에 의해 결정된다고 했다.
      • 난 무슨생각을 했을까? 일기를 보고싶다. - 김준석

4.2. 라이프 구조를 차트로 표현하기

  • p143
    • 이해하려 할 때엔 정적인 구조부터 살펴보는 것이 큰 그림을 잡기에 좋다.

    • 이 그림은 잡다한 세부 사항을 생략하고 핵심 디자인 패턴만을 보여준다.

    • 실세계에서 패턴을 사용하는 법을 그대로 보여준다.

  • p146
    • 이들 다이어그램을 프로그래머인 내 아내 데어드리에게 처음 보여주었을 때 그녀의 반응은 "너무 복잡해요. 이런 다이어그램은 보고싶지 않은걸요?" 였다. 하지만 앞으로 여러분과 함께 할 것과 같은 방식으로 시스템에 대해 살펴보고 난 뒤에 그녀의 반응은 "이 다이어그램의 표현력은 정말 대단하군요! 풍부하다(rich)는 말이 적합할 것 같아요"로 바뀌었다.
      • 아내도 프로그래머다. 진정한 화개장터시다. 마치 엄마 코딩봇처럼.. - 김준석

    • '복잡한'에서 '풍부한'으로의 전이는 중요한 것이며, 여러분이 별 어려움 없이 패턴을 응용할 수 있을 때 일어나는 현상 중 하나이다.

    • 패턴 '잘라 붙이기(cut-and-paste)'란 개념은 넌센스이다. 패턴은 멋지게 분리하여 갈끔하게 잘라 붙일 수 있는 방식으로는 거의 사용되지 않는다.

4.3. Clock 서브시스템 : Observer 디자인 패턴


  • p147
    • 객체들(Observer)에 주기적으로 클록 틱(clock tick)이벤트를 통지한다. 이 경우는 Universe가 ActionListener 인터페이스를 구현한 익명의 내부 클래스를 통해 이벤트를 받는다.
      • Tick Tick Tick Tick... 시간은 Universe하지. - 김준석

  • p148
    • class BadJmenuItem
    • 상속을 이용하여 이벤트 통지를 하면 이벤트를 발생시키는 객체와 이벤트를 처리하는 객체 사이에 결합도가 매우 높아진다.

    • 패턴의 의도를 잘 나타내주는 훌륭한 이름이다.
      • Naming은 항상 중요하지. 근데 아직도 난 잘 모르겠단 말야 - 김준석

  • p149
    • 이벤트 통지는 출판자에서 구독자에게로 직접 배달된다. '중개자' 객체를 생성하고 유지 보수할 필요가 없게 된다.
      • 중간 마진을 빼면 소비자와 판매자가 만족합니다. - 김준석

    • Clock은 Subject/Publisher 역할을 맡는다.

  • p151
    • Clock이 전형적인 GoF Singleton 임을 주의 깊게 보기 바란다.

    • 좀 더 단순한 구현을 사용하려 시도해 보았늗네 Clock Singleton이 너무 일찍 생성되어 메뉴가 올바로 설정되지 않는 문제가 발생했다. '고전적'인 Singleton이 이런 문제를 해결해 준다.
      • Java는 플렛폼 기반이기 때문에 나오는 문제로 '고전적'인 Singleton은 컴파일동안 해당 Singleton 클래스를 구성할 충분한 정보를 가지는 기회를 주기때문에 이런문제를 해결해 주는것이다. 역시 책을 읽은 보람이 있군! - 김준석

4.3.1. Observer 구현하기 : Publisher 클래스


  • p154
    • 지금까지 많은 개발자들의 경험을 통해 Observer는 구현하기 매우 어렵다고 밝혀졌고, 특히 스윙과 같이 여러 스레드가 상호 작용하는 환경에서는 더욱 그러하다.

    • 모든 실제 처리는 스윙 이벤트 스레드에서 일어나며, 이 이벤트 스레드가 사용자 입력 액션에 반응한다. 하지만 나는 여러 스레드 중 메인 스레드에서 메인 객체 모델이 동작해지는 스윙 이벤트 스레드로부터 발생하고, 스윙은 많은 비동기 메시지를 메인 객체 모델에 보내게 되는데, 메인 스레드는 스윙 이벤트 스레드가 언제 이벤트를 보낼지 예측할 수 없다.
      • 스윙은 정말 많은 문제를 포함하고있다는걸 다시, 다시 느낀다. 사실 스윙뿐만이 아니지만 - 김준석
        • 위 글은 이벤트의 예측 불가성을 이야기 하는거 아닌가요?; 스윙의 문제가 아닌듯 - 서지혜

  • p155
    • 스레드를'굶겨 죽일 수도'있게 된다.
      • ... 아사는 무서운것이야 - 김준석

    • 만약 이와 같은 '기아'를 없애기 위해 fireEvent()에서 Synchronized를 제거한다 하더라도 역시 고약한 문제가 발생한다. 어떤 스레드에서 subscribe()혹은 cancle()메소드를 수행하는 동안, 다른 스레드에서 fireEvent()를 수행시킬 수 있기 대문이다. 동기화를 하지 않는다면 구독 객체 리스트를 수정하는 도중에 다른 스레드에서 접근할 수 있게 되기 때문에 결과적으로 subscribers 리스트가 망가질 위험이 있다.
  • p156
    • 예외를 사용하는 방법은 Observer에 너무 많은 짐을 떠넘기는 것이다.

  • p157
    • 이벤트 통지가 복사본으로부터 이루어지므로 구독 객체가 구독을 취소한 후에도 이벤트 통지를 할 가능성이 있다.

    • 코드를 방어적으로 작성하기 바란다.

    • 뒤에서 살펴볼 코드3-3에 있는 Publisher 클래스는 복사를 너무 많이 하는 문제를 멋지게 해결한다.
      • 스토리텔링 하나는 멋지게 하시는것 같다. -김준석

    • Command 객체가 Observer에 어떻게 통지할 것인가에 대한 정보를 캡슐화하기 때문에, Publisher는 통지 매커니즘을 Command객체에 위임할 수 있다.
  • p159
    • Node의 모든 필드는 final이므로 Node는 '불변(immutable)'객체이며 한 번 생성하면 수정할 수 없다. 결과적으로 여러 스레드가 Node 객체에 접근하더라도 안전하며 동기화를 하지 않아도 된다.
  • p160
    • 만약 외부 클래스의 메소드가 내부 클래스에서 선언된 접근 권한을 어기면서 접근하고 있다면 약간의 유지 보수성과 약간의 코드 단순화를 맞교환 하고 있는것이다.
      • 어투는 좀 잘못된 Trade-Off라고 하는듯 하다. - 김준석

  • p161
    • 많은 프로그래머들이 재귀 알고리즘이 불분명하고 비효율적이기 때문에 언제나 '나쁘다'고 생각하고 있는 것같다.
      • 그 양이 얼마나 될지 불분명하기 때문에 '복불복'느낌이 들어 비효율적이지 - 김준석

    • 재귀를 이용한 구현에서는 노드에 대한 레퍼런스가 각 재귀 호출의 로컬 변수이기 때문에 이를 유지하기 매우 쉽다.


4.4. Clock 서브시스템 : Visitor 패턴

5. 소형 데이터베이스 구현하기


  • 오랜만에 이 페이지 다시 보고있는데 준석선배께서 꾸준히 밑줄을 열심히 긋고계셨다는 사실에 새삼 감탄하고 갑니다...! - 김수경

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:25
Processing time 0.1854 sec