[[TableOfContents]] == 소프트웨어 설계의 고고학 == === 설계 원칙 === * p.1 * 복싱에서는 스트레이트, 잽, 훅, 이 세가지 펀치를 기반으로 다른 모든 종류의 펀치가 나온다고한다. ~~~ 이러한 기본 자세가 튼튼하다면 그만큼 다른 펀치를 배우는 데도 진입 장벽이 낮아지기 때문이다. * 스포츠를 사용해서 비유를 하는건 쉽게 이해는 되는데, 항상 별로 재미없어. - [김준석] * 다른 종류지만 검도는 내려치기 자세만 천번인가 연습한다고 합니다. 하루에(만화책이었음ㅋㅋ) 그만큼 기본기가 중요하다는 말이겠죠 - [서지혜] === 의존관계 === * p.3 * 슬프게도 개발자 입장에서는 의사 결정에 참여하여 변경에 대한 요구를 막지 못하는 것이 대부분이다. * 요구사항의 변경같은경우 어쩔수 없지만 기술적인 부분이라면 개발자가 가장 힘있지 않나? - [김준석] * 그건 인도개발자만.. - [서지혜] * 힘이라는 건 고객과 경영진에게 있을걸요ㅠㅠㅠㅠ 일개 개발자는 수드라... - [김수경] == OO와 디자인패턴 기초 다지기 == === 패턴 vs 이디엄 === * p.22 * 이디엄은 일상적으로 사용하게 된 패턴이다. * 지난주엔 이 말 떄문에 혼란스러웠는데 책에서 다시 보니 왜 혼란스러웠는지 모르겠어요. - [김수경] * 난 책보고도 이상한 말이라는 생각밖에 안드는군. - [김준석] * 1980년대 초 C언어가 왕이었을 무렵 상속은 하나의 디자인 패턴이었다. * 지금은 이디엄이 되어 누구나 아무 생각 없이 사용하는 상속이 패턴이었다는 사실도 재미있고 C언어가 왕이었다는 표현도 재미있네요. - [김수경] * 요즘은 상속과 인터페이스 같은 기능이 많은 언어에 내장되어 있다. 이들은 이디엄이 된 것이다. * 에 달린 역자주석을 보니 노스 화이트헤드가 "문명이 진보한다는 것은 인간이 의식적인 노력 없이 자동적으로 수행하는 활동이 증가하고 있음을 의미"한다는 지적을 했다고 한다. 이디엄은 과연 좋은것인가? 이디엄이야말로 생각없이 적용하는 패턴이 아닌가? - [서지혜] * 다양한 사례에 적용해서 적용되기 전보다 높은 효율을 보일 수 있다는 것이 충분히 검증되었기 때문에 이디엄이 되는 것 아닐까요? 물론 모든 것에 100% 적용되는 이디엄이란 존재하지 않겠지만요. - [박성현] * 무책임한 상속은 오히려 변화의 크기를 증가시키기도 합니다. 이디엄이라고 반드시 옳은것은 아닌듯ㅋㅋ - [서지혜] * 이디엄은 가치 중립적이지. 이디엄을 생각없이 적용하는 것이 나쁜것이고. - [김수경] * 오늘 얘기하면서 깨달았다. 이디엄이 패턴보다 더 습관적으로 적용하기가 쉬울테니(패턴을 몰라도 이디엄은 쓸수있음) 역자가 저런말을 쓴건가봐 - [서지혜] === 디자인패턴이란 무엇인가? === * p.22 * 먼저 패턴은 발명되는 것이 아니라 발견되는 것이라는 사실을 이해해야만 한다. * 패턴이 목적이 아니라 어떤 의도를 구현하기 위해 만든 코드들에서 비슷한 패턴이 발견된다고 한다. - [서지혜] * p.23 * 그러므로 패턴은 해결 방법 그 자체라기보다는 해결 방법의 일반 구조라 할 수 있다. * 패턴은 어떤 류의 문제를 해결하기 위해 사용되는 일반적인 기술이다. * 패턴은 이와 같이 일반적인 해결 방법이기 때문에 한 프로그램에서 다른 프로그램으로 디자인패턴을 복사해 붙여넣는 것은 거의 불가능하다. * 그들은 패턴 자체를 패턴을 설명하기 위해 사용한 코드와 혼동하고 있는 것이다. * 이 책을 안읽었다면 나도 패턴과 코드를 혼동하는 실수를 했을것같다.. 사람들은 처음 배운것을 진리라 여기는 경향이 있고 비판하기도 사랑하니까. "패턴은 그게아냐!! 이거라고!!" - [서지혜] * p.24 * 현실에서는 한 패턴에 참여하고 있는 객체와 클래스가 동시에 다른 패턴에서도 사용되는 경우가 매우 많다. * 패턴에 입문한 지 얼마 안 되는 초보자일수록 무언가 멋져 보이는 클래스 다이어그램에 관심을 쏟는데, 더욱 중요한 것은 '패턴의 의도'(혹은 목적)와 '동적인 행동양식'이다. * '동적인 행동양식'이 무엇인지 잘 감이 오지 않네요. - [김수경] * '동적인 행동양식'은 패턴을 통한 목적 달성에 이루기까지 흐름이 어떻게 이루어지는지에 대한것 같아 -[김준석] * 저자가 정적구조가 아닌 동적 행동양식에 신경을 써라라고 말하는거 보니 실행시간에 일어나는 어떤 변화같은데.. - [서지혜] * 객체들의 상호작용을 동적 행동 양식이라 하는듯 - [서지혜] * 시원하면서도 안락한 느낌을 주는 방들을 살펴보면 앞으로 '교차 통풍'이라 부를 패턴이 창발한다. * 강의실에서 ''공대 냄새''가 나는 이유를 알았습니다. 강의실은 '교차 통풍' 패턴에 속하지 않아요. - [김수경] * 하긴 시원하면서도 안락하지 않은게 공대 강의실이지 - [김준석] * 시원하지도 않은데.. 근데 어제 핸드폰 찾으러 교양학관같는데 거기는 더 심하더라..우엑 냄새나는 찜질방이었음 - [서지혜] * 이 의도를 만족시킨다면 어떤 구조든 이 패턴의 합당한 실체화가 된다. * p.25 * 패턴의 실체화는 디자인이지 코드가 아니며, 하나의 디자인은 여러 가지 합당한 방법으로 구현할 수 있다. * 패턴의 실체화 방식은 다양하지만 여러분이 좋아하는 요소만 쏙 뽑아 사용할 수는 없다. * p.26 * 남서쪽 창은 두 개의 패턴 모두에 참여하고 있다는 점에서 흥미롭다. * p.27 * 중요한 것은 구조를 통해서만 패턴을 파악하는 것이 불가능하다는 사실을 이해하는 것이다. * 패턴을 찾아내려면 아키텍처의 의도를 포함한 문맥 정보가 필요하다. * 생각 없이 패턴을 복사하고 붙여넣는 것은 마음대로 낙서를 한 뒤 멋진 그림을 주장하는 것과 같은 우매한 것이다. * 나도 이런적이 있었지 패턴을 쓴다고 다 좋아지는게 아니니까 - [김준석] * 피카소가 생각난다 - [서지혜] * 패턴은 디자인으로 실체화 되고 디자인은 구현으로 실체화 된다. * 구현은 추상화 시켜 디자인이되고 그것을 추상화시켜서 패턴이된다 - [김준석] === 패턴, 무엇이 좋은가? === * p.28 * 즉 패턴을 사용하지 않고 설명하는 것보다 훨씬 짧고 훨씬 명확했다. * p.29 * 패턴은 커뮤니케이션을 극적으로 향상시켜주는 유기적 프레임워크를 제공하며 결국 이것이 디자인의 모든 것이다. * 하지만 커뮤니케이션의 당사자들이 모두 패턴을 알고있다는 전제 하에 가능한 일. - [김수경] === 디자인에서 패턴의 역할 === * p.29 * 패턴은 구현에 대해 생각하기 시작할 때 등장하게 된다. * 건축 계획은 모든 축조 새부 사항을 설명하지는 않는다. 즉 어디에 벽이 있어야 할지를 보여줄 뿐 벽을 어떨게 만들어야 하는지에 대해 설명하지는 않는 것이다. * p.30 * 디자인 패턴은 보통 디자인 문서에 상세히 나타나지는 않으며 구현하는 사람이 내리는 결정을 나타내 준다. * 구현은 스스로 말할 뿐이다. * 토킹코드인가!!! - [서지혜] * 내코드는 가끔 그러더군 ''왈왈'' - [김준석] ==== 패턴과 단순함 사이의 긴장 ==== * p.30 * '우둔한 프로그래머와 아키텍처'는 패턴이 항상 좋은 것이며 가능한 모든 곳에서 사용해야 한다고 일관되게 믿는다. * p.31 * 프로그래머들은 미래에 등장할지도 모를 요구 사항까지도 추가하는 경향이 있다. * 미래에 변화될 것이라 생각하기 때문에 코드를 복잡하게 하는 것은 좋은 생각이 아니다.(적어도 내 경우는 미래를 예측하려 할때마다 내 예상이 빗나갔다.) * 요구되는 기능을 삭제하는 것은 불필요한 기능을 추가하는 것만큼 나쁘다. * 요구되는 기능을 왜 삭제하는가? 요구되는 기능을 구현하는게 우리 일 아닌가? -[임상현] * 요구 기능을 구현하는게 어렵다며 맘대로 다른거 붙이는 사람도있음.. 예를들면 파일을 삭제할때 복구기능을 만들기 싫어서 확인 다이얼로그를 띄우지.. - [서지혜] * 그리고는 구현하고 나서는 스스로 납득을 하게 됩니다. '이러이러하게 하는게 더 좋은 사용자 경험을 제공할 수 있을거야.' 는 무슨 -_-; - [박성현] * 구현은 복잡한데 돈을 조금 준다면 삭제해버리겠지. - [김수경] * 프로그래머는 지금 앞으로 어떻게 될지 모를 기능을 추가하는 것이 아니라 새로운 기능을 추가하거나 기존의 것을 수정하기 쉽도록 프로그램을 작성해야 하는 것이다. * 우리는 필요로 하는 바로 그것을 해야한다. * 사용자가 무언가를 정말로 하고 싶어한다면 이에 대해 질문하지 말아야 한다고 주장한다. * 확실히 근근히 나오는 확인 팝업창 겁나 귀찮습니다. -[임상현] * 실수했다 생각되면 되돌릴 수 있도록 만들어 줘라. 그래서 휴지통은 편하지. 절대 영구삭제 하면 안돼 - [서지혜] * p.32 * 단순함 , 완전성 그리고 수정의 용이성이란 세가지 요구 사항은 상충되기도 한다. * 인터페이스는 패턴 전체를 도입하는 것과는 달리 그다지 복잡성을 증가시키지 않는다. 반면 기능 변경이나 추가 시 리팩토링이 쉬워진다. === 패턴 분류하기 === * p.32 * 패턴을 분류하는 것은 필요한 상황에서 적절한 패턴을 선택하는 것을 용이하게 해준다는 점에서 유용하다. * p.34 * 패턴들이 서로 의존하고 있다는 사실을 이해하는 것도 중요하다. * 여러 패턴들이 서로 관련이 있으며 실제 프로그래밍할 때는 이들을 엮어 함께 사용하는 경우가 많다는 사실만 명심하면 된다. * p.34 * 패턴 간의 연관성 의존성 때문에 한 패턴을 다른 패턴과 구분하기 어려울 수도 있다. 이럴 경우에는 정적 구조 대신 패턴의 의도에 초점을 맞추기 바란다. ==== 디자인 일반 ==== * p.35 * 객체 지향 디자인(OOD)과 객체 지향 프로그래밍(OOP)은 매우 다른것이다. * 디자인 프로세스는 유스케이스 분석등을 통한 요수사항 수집에서 시작해 코딩이 시작되는 디자인으로 끝나게 된다. * 프로그래밍 프로세스는 디자인에서 시작하며 상속, 캡슐화, 디자인 패턴 등을 이용하고 디자은의 실체인 컴퓨터 프로그램을 내놓는다. * 이와같은 기술의 융합은 애자일(Agile) 방법론에서 특히 중요한데 디자인과 코딩이 병렬적으로 진행되기 때문이다. * 애자일을 하려면 디자인, 코딩을 둘다 할줄 알아야 하나.. - [서지혜] * 어떤 애자일 방법론도 춤추는 꼭두각시 프로그래머와 이를 조종하는 아키텍트란 도식을 지지하지 않는다. * ''YES맨이 되지 말아라''는 건가? - [서지혜] * 프로그래머도 아키텍쳐를 이해해야한다는 것 아닐까? - [김수경] * 아하, 자기가 어디의 뭐를 하는지는 알아야 한다는 뜻? - [서지혜] ==== 자바를 C언어 스타일로 프로그래밍하기 ==== * p.37 * 절차 지향 프로그래밍은 데이터를 조작 혹은 검토하는 서브루틴 간의 데이터 흐름을 구조화 한다. * 사실 많은 절차 지향적 프로그램은 사용자 인터페이스를 통해 데이터베이스 테이블을 보여주는 역할을 할 뿐이다. * 객체 지향 시스템은 상호 협동하는 에이전트들의 네트워크이며, 에이전트는 메시지를 통해 통신한다. * 객체 지향 시스템과 절차 지향 시스템을 구분하는 한가지 좋은 방법은 무언가를 변화시킬 때 어떤일이 발생하는가를 보는 것이다. * 설계할 때 이것을 미리 상상해보면 도움이 되는 것 같아요. ''과연 내가 이렇게 짜면 이런 변경이 생길 때 어떻게 될까?'' - [김수경] * 절차 지향 시스템에서는 변화가 프로그램의 나머지에 '퍼져나가는'경향이 있다. * 객체 지향 시스템에서는 변화가 한곳에 집중되는 경향이 있다. * p.39 * 내가 MFC가 상당 부분 객체 자향적이지 않다는 이야기를 하자 그의 대답은 자신도 알고 있다는 것 이었다. * 내가 MFC가 객체 지향적이지 않다고 말했을때 상대는 MFC야말로 객체지향적이다 라고 했던 것 같다. - [서지혜] * p.40 * 절차 지향적 해결 방법이 본질적으로 나쁜 것은 아니다. 하지만 선택을 할 때는 이 선택에 따르는 위험까지 고려해 보기 바란다. ==== 열린 눈으로 프로그래밍하기 ==== * p.40 * 디자인은 선택과 트레이드 오프, 리스크 관리의 연속이다. * 어떤 디자은을 ''선택''할 때는 선택으로 인한 장단점을 고려(''트레이드 오프'')해야 한다. 그리고 그것을 취한뒤에는 그로인해 잃은 것을 감내해야한다(''리스크 관리'') 이게 맞나? - [서지혜] * 자신이 하고 있는 일이 어떤 결과를 초래할지를 알지 못한다면 이는 디자인을 하고 있는 것이 아니라 어둠 속에서 비틀거리리고 있을 뿐이다. * 디자인이 아닌 구현단계에서도 이러한 상황을 "''우연에 의한 프로그래밍''"이라고 설명을 하더라고요. 그리고 대부분의 개발자는 "''우연에 의한 프로그래밍''"을 하고 있다고... 실용주의 프로그래머에서 본 기억이 있네요..? - [박성현] * faith coding과도 상통하는 말인가ㅋㅋ - [서지혜] * p.41 * 어떤 언어의 기능 혹은 이디엄이 초래할 수 있는 폐해를 이해하면 해당 기능과 이디엄을 사용하는 것이 적절한지 아닌지 좀 더 현명하게 결정할 수 있다. === 객체란 무엇인가? === ==== 허튼소리! ==== * p.42 * 우선 OO 시스템을 지능 있는 동물(객체)의 모임이라 생각하자. * OO 디자인에서 가장 중요한 원리는 데이터 추상화이다. * "객체는 메소드라 불리는 함수가 있는 자료 구조이며 메소드가 자료 구조를 조작한다."라는 설명을 보았을지도 모르겠다. 허튼소리! 당치 않다. * 봉봉 생각나! 봉봉도 그책을 읽은게 아닐까?- [김준석] * 나도 객체지향은 어떤 작업에 대한 데이터와 메소드를 객체가 가지고 있는 것이라고 생각했음!! - [서지혜] * 이러한 착각은 흔히 C를 배우고 C++을 배울 때, '객체'가 아닌 문법 클래스'를 쉽게 설명하려고 "클래스는 structure(data) + method(to do) 이다." 라는 요상한 설명을 접하게 되면 하게 되는 것 같습니다. 처음에 이런 설명을 접하게 되면 나중에는 생각을 바꾸기 어려워지죠 (아니 귀찮아지는 건가...) -_-;; - [박성현] * 정답. 클래스는 구조체+메소드에요 라는 설명을 열혈강의 c++에서 본듯..? - [서지혜] * 2학년땐 나도 저렇게 생각했다ㅜㅜㅜ [Spring/탐험스터디]에서도 얘기했지만 그래서 객체지향설계라면 메소드만 있는 클래스는 존재해선 안된다고 말한 적도 있음ㅜㅜㅜㅜ 부끄럽다... - [김수경] ==== 객체는 기능의 집합이다 ==== * p.43 * OO의 제 1 지령. 객체에 어떤 작업을 하는 데 필요한 정보를 요청하지 말라. 대신 작업을 하는 데 필요한 데이터를 갖고 있는 객체에 일을 해달라고 요청하라. * 켄 아놀드는 다음과 같이 말한다. "정보가 아닌 도움을 요청하라(Ask for help, not for information)." * 이건 굉장한 개념이야!!! ''너! 일해!'' -[김준석] * ''도움을 요청하라''는 말을 보니 만객체(-_-;;)는 평등하다는 말이 생각나는군 - [서지혜] * 귀족 객체는 없다!!!! - [김수경] * 중요한 것은 원리이지 사용하고 있는 언어가 아니다. * 자바가 객체지향 프로그램을 줄거라 생각하지마!! - [서지혜] * 이건 6피의 중심에서 외치고 싶은 말. 많은 후배들이 이런 질문을 한다. ''C로는 객체지향 못하는거 아니에여?'' ;;;;;;; 혹은 ''OOP로 짜고있어요 ㅋ''해서 보면 자바로 짠다는 것 외엔 도대체 객체지향의 원리가 어디에 녹아있는지 알 수 없는 코드라거나... 클래스 쓰면 다 OO냐ㅜㅜ 그렇게 간단하면 학교에서 왜 한학기나 할애해서 배우겠어. - [김수경] * 한학기를 할애해도 못 가르치고 못배우니 저렇게 쓰겠지 - [서지혜] ==== 어떻게 잘못하고 있는가? ==== *p.45 * OO는 컴퓨터 프로그램에 내재하는 피할 수 없는 복잡성을 조직화 하는 것이지, 복잡성 자체를 제거하는 것이 아니다. * 이러한 룰을 따르면 문제점을 고치거나 새로운 기능을 추가함으로써 발생하는 변화가 한곳에 집중된다. 이때 유지 보수가 용이하다는 것과 복잡하지 않다는 것을 혼동하지 말기 바란다. *p.48 * 잘못된 마인드를 가진 프로그래머는 모든 언어를 이용해서 쓰레기 코드를 작성해 내는 마법을 부릴 수 있다. * wow. 과격한데 - [서지혜] * 난 법사였군... - [김수경] ==== 어떻게 '올바르게' 할 수 있는가? ==== * p.48 * 리라(lira)를 통화로 사용하던 이탈리아가 유럽의 단일 통화인 유로(euro)를 사용하게 되면서 겪었던 고통을 상상해 보자 * 무슨일이 있었지?? 궁금하다 - [서지혜] * 만약 빌 게이츠가 은행에 걸어들어와 계좌를 개설한 뒤 그의 모든 재산을 예금하겠다고 하면 어떻게 될까? 여러분이 은행 지점장이라면 절대 빌이란 고객을 놓치고 싶지 않을 것이다. * 역시 빌게이. 돈의 힘이란. -[김준석] === 셀룰러 오토마타 === * p.52 * 셀룰러 오토마타(Cellular automata)의 프로그램 구현은 OO 시스템의 훌륭한 예가 된다. 셀룰러 오토마타 프로그램은 복잡한 문제를 정확히 객체 지향적인 방식으로 해결한다. * 이런 흐름을 만들수 있어야하는데.. - [김준석] * 교통 흐름을 예측하는 것은 카오스 이론이 해결하려는 유명한 문제이며,, 그 해결은 매우 어렵다. 이때 시뮬레이션 모델의 행위에 기반하여 예측할 수 있다는 가정을 한다면 교통 흐름을 모델링, 시뮬레이션하는것이 유용할 것이다. * SimCity!!!! - [김준석] * 스터디 하다말고 심시티에 빠진 김준석씨... - [서지혜] * p.54 * 모든 OO 시스템과 마찬가지로 이러한 종류의 룰은 주변 코드에 영향을 미치지 않으면서도 바뀔수 있다. * p.55 * 어떤 객체는 자신이 포함하고 있는 객체에 해당 객체가 필요로 하는 외부 정보를 넘겨줌으로써 문제를 해결한다. 즉 위임을 통해 문제를 해결한다. 메시지가 위임하는 객체로 전달되어 갈수록 추가적인 인자를 포함하는 경향이 있다. * 좋은 클래스는 getter와 setter메소드를 갖지 않는데, 이런 메소드는 구현 상세를 노출시키기 때문에 결과적으로 유지 보수를 어렵게 만들기 때문이다. 예를 들어 getter 메소드의 리턴 타입이 바뀌게 되면 getter를 정의하는 객체뿐 아니라 'getter'를 호출하는 모든 코드 또한 바꾸어 주어야 한다. 잠시 후에 getter와 setter 메소드 없이 시스템을 디자인하는 방법에 대해 설명할 것이다. 기대해도 좋다. * p.56 * 보라고! 차들이 도시 안을 돌아다니잖아!! === 접근 메소드와 수정 메소드는 나쁘다 === * p.57 * 이 말이 메소드가 값을 반화하면 안 된다거나 'get'혹은 'set'기능이 언제나 부적절하다는 것은 아니다. 객체는 때때로 시스템 전반을 흘러다니며 작업을 수행하도록 도와주어야 한다. 하지만 많은 경우 get/set 메소드는 private 필드를 접근하는 용도로만 부적절하게 사용되며, 이런 사용이 많은 문제를 발생시킨다. * p.58 * 유지 보수성의 최대 적 중 하나인 중복 코드를 작성해야 한다. * p.60 * 이미 데이터를 갖고 있는 객체가 일을 하게 하는것은 어떨까? 다시 말해 신의 클래스에서 접근 메소드를 통해 가져온 데이터를 갖고 어떤 작업을 하는 코드를 이 데이터를 저장하고 있는 객체로 옮기면 어떨까? 접근 메소드는 사라지고 코드는 단순해진다. * 아무 생각 없이 접근 메소드와 수정 메소드를 사용하는 것은 public 필드를 사용하는 것이 위험한 것과 같은 이유로 똑같이 위험하다. * 생각해보니 get, set이랑 public이랑 다를게없다.. - [서지혜] * 구현은닉이라는 원리는 객체 지향 시스템의 품질을 평가하는 좋은 지표가 된다. 클래스의 구현을 마음대로 바꾸어도, 심지어 기존 클래스를 버리고 새로운 클래스를 작성하더라도 이를 사용하는 객체의 코드에는 영향을 미치지 않을 수 있는가? * 만약 구현 은닉을 하지 않는다면 다른 OO기능을 사용하는 것이 큰 의미가 없게된다. * p 62 * 이러한 '추측에 의한 디자인하기'전략은 사용하지도 않는 메소드를 작성하는데, 즉 필요치 않은 기능을 클래스에 추가하는 데 불필요한 시간을 낭비하게 한다. * 음? 디자이너들의 상상 디자인인가? - [서지혜] ==== 스스로를 표현하라 ==== * p.62 * 내가 실제로는 비지니스 로직에 어떤 UI 코드로 삽입하지 않았다는 사실을 기억하기 바란다. ==== 자바빈즈와 스트럿츠 ==== * p63 * 불행히도 아무도 이러한 getter/setter를 이런 의도대로 사용하지 않았다. ==== 리팩토링 ==== * p65 * 이클립스는 현재 프로젝트의 범위에서만 리팩토링해 준다. * 두번째로, 자동화된 리팩토링은 단순한 작업에는 매우 휼륭하게 동작하지만 큰 변화에는 그렇지 못하다. * 코드가 올바른 방식으로 구조화되지 않았기 때문에 유지 보수가 필요 이상으로 어렵다는 것이다. 이런 경우 리팩토링이 아닌 프로그램의 재디자인이 필요하다. ==== get/set 없는 삶 ==== * p 67 * CRC카드를 통한 첫 번째 시도는 '어림 잡기'일 뿐이다. * p68 * 어떤 사람들은 이러한 방식으로 CRC카드를 이용해 실제 프로그램까지도 디자인하지만 이 방식은 복잡한 대규모 프로그램까지 수용할 정도로 효율적이지는 않다. 대부분의 프로그래머는 정식 프로세스를 사용하여 UML로 동적 모델과 정적 모델을 개발한다. * 모델링은 내가 마지막 경험 법칙에서 언급했듯이 가능한 '문제 도메인'안에 머물러 있어야 한다. 하지만 많은 개발자들이 자신은 문제 도메인을 모델링하고 있다고 생각하지만 실제로는 구현 레벨에서 모델링을 한다. ==== 언제 getter와 setter를 사용해도 괜찮은가? ==== * p69 * 데이터를 '꺼내는(pull)'것보다는 '넣는(push)'것이 보다 좋다. * '어떤 용도로 사용될지를 모두 예측할 수 없어'와 같은 문제는 자바 패키지 전반에 퍼져 있다. 이런 경우 이미 말했듯이 객체에서 모든 getter와 setter를 제거할 수 없다. ==== getter/setter 이슈 정리 ==== == 인터페이스로 프로그래밍하기 그리고 몇 개의 생성 패턴 == * 75p * 인터페이스 관점에서 프로그래밍 하는 것은 OO 시스템의 기본 개념이며 GoF와 디자인 패턴은 이의 구체적이 예가 된다. * 하지만 많은 자바 프로그래머들은 인터페이스를 거의 사용하지 않고 extends 관계를 남용하고 있다. * 네 저요. - [서지혜] === 왜 Extends가 나쁜가? === * 75p * extends 키워드는 나쁘다. * ... 명성 있는 디자이너라면 가능한 사용을 자제할 정도로는 충분히 나쁘다. * ... 혹시라도 내가 extends를 절대 사용하면 안 된다고 주장하고 있다고 생각하지는 말기 바란다. * 아저씨 많이 까임의 증거 -[김준석] * 디자인 패턴은 크게 보면 구현 상속(extends)을 인터페이스 상속(implements)으로 바꾸는 방법을 설명하고 있다. * 76p * "많은 사람들이 '우리 회사의 제품은 C++을 이용해 만들었기 때문에 객체 지향적입니다' 라고 설명했다는 CEO에 대한 이야기를 한다. 그런데 이 중 어떤 이들은 이 이야기가 농담이란 사실을 모르고 있다. * 재미있네요. 나는 mfc는 객체 지향적이다 라는 말과 알수없는 클래스들을 만들어 놓고 객체지향이라고 한 말을 들은적이 있습니다. - [서지혜] * 자바 프로그래머들은 종종 extends와 같은 언어의 기능을 객체 지향 자체와 혼동하곤 한다. * 네 저요. - [서지혜] * 다형성이란 개념은 OO의 고유한 특성이며, 다형성을 사용하지 않는 프로그램은 객체 지향적이지 않다는 주장은 설득력있다. * OO 시스템에서는 데이터 캡슐화가 선택이 아닌 필수이다. * 77p * extends와 implements 간의 유사성은 C++ 언어에서는 명확하다. C++는 이 둘을 구분하지 않기 때문이다. * C++을 배우고 자바를 배우면 익숙한 구현 상속을 많이 사용하게 되지. C++에도 인터페이스의 개념이 있지만 시작부터 구체 클래스를 만드는 습관때문에 거의 쓰지 않았었다. - [서지혜] === 인터페이스 vs. 클래스 === ==== 유연성의 상실 ==== * 77p * 구현 상속이 도대체 왜 나쁠까? 명시적으로 구체 클래스의 이름을 사용하면 특정 구현에 종속되는데 이는 결과적으로 수정을 필요 이상으로 어렵게 만든다. * 78p * 애자일 방법론이 모든 프로젝트에 들어맞는 것은 아니지만, 개발 기간 동안 요구 사항의 변화가 있는 중소 규모 프로젝트에는 매우 효과적이다. * 중소규모 말고 대규모 프로젝트는 어떨까...? - [김준석] * 애자일 병행 개발의 중심에는 유연성이란 개념이 있다. 새로 추가된 요구 사항을 쉽게 반영할 수 있는 코드를 만든다는 것이다. 또한 아마도 필요할지도 모르는 기능을 구현하기보다는 꼭 필요한 기능을 구현하되, 프로그램은 변화를 수용할 수 있어야 한다. * 애자일이란 민첩하게 대응한다는 뜻이다. 이런 의미에서 애자일이 변화를 수용할 수 있는 객체 지향을 사용하는 것이 당연한듯하다. - [서지혜] * ... 변화는 이런 식으로 파급된다. ==== 결합도 ==== * 80p * 예를 들면 상수가 아닌 모든 필드는 항상 private이어야 한다. 정말? 예외는 없다. 절대로! * protected 인스턴스 변수는 정말 역겹다. protected 변수는 public을 의미하는 다른 방법일 뿐이다. * 나는 구현 상속을 사용할 때 get/set을 만드는 것도 귀찮아 protected를 썼었는데, 마치 나에게 하는 말 같군. 기분이 안좋아진다... - [서지혜] * p81 * 나는 개발을 하면서 OO 원칙 적용의 '엄격성(strictness)'과 코드를 빨리 작성하고 유지 보수하기 좋은 코드를 작성하는 것 사이에 높은 상관관계가 있다는 사실을 깨달았다. * 어느정도 의심가는 부분이 있는경우는 꼭 고쳐야되게되더군 - [김준석] * 코딩하다가 어느 순간, 이거 좀 잘못하고 있는거같은데.. 하는 순간이있다. 그걸 애써 무시하고 넘어갔는데 토이 수준이 아니라면 큰 문제였겠지.. - [서지혜] ==== 깨지기 쉬운 기반 클래스 문제 ==== * p81 * 기반 클래스는 기반 클래스만을 따로 떨어뜨려 놓고 안전하게 수정할 수 없으며, 모든 파생 클래스를 함께 살펴보고 테스트해 보아야 한다. * 슈퍼 클래스를 수정하면 알수없는 새끼 에러들이 창발한다ㅋㅋㅋ - [서지혜] * p86 * 구현 상속을 사용하면 기반 클래스를 수정할 때마다 파생 클래스들이 제대로 작동하는지를 테스트해야 한다. * p87 * 기반 클래스를 수정할 때마다 파생 클래스를 검토해 보아야 한다면 이는 기반 클래스를 확장하고 있는 것이 아니라 인터페이스를 구현하고 있는 것이다. * 그러고보니 일일이 오버라이딩할 바에는 인터페이스를 implements하는게 더 나을거같네? - [서지혜] ==== 다중 상속 ==== * p90 * 구현 상속이 '나쁘다면' 분명 다중 구현 상속은 더 나쁘다. ==== 프레임워크 ==== * p91 * 깨지기 쉬운 기반 클래스 문제를 프레임워크 기반 프로그래밍에 대한 언급 없이 마칠 수는 없다. MFC(Microsoft's Foundation Class) 라이브러리와 같은 프레임워크는 클래스 라이브러리를 만드는 인기있는 방법이 되었다. * 나는 처음부터 MFC가 별로 마음에 안들었다. 기능을 하나 구현하려면 이곳저곳을 손대야 해서.. - [서지혜] * 마이크로소프트의 문제 해결 방식이 항상 올바른 것은 아니다. * 수경이가 읽어주었던 MS사의 직원들이 말하는건 도움이 안된다는게 기억나는군. - [김준석] * 개떡같은 UI랑은 다른 문제인거같은데요ㅋㅋㅋ 마소가 자주 까이는건 그만큼 영향력이 크다는 말일듯 - [서지혜] * p92 * 구현 상속 기반 아키텍처는 깨지기 쉬운 기반 클래스 문제 외에도 너무 많은 클래스를 구현해 주어야 하는 문제를 갖고있다. ==== Template method와 Factory Method 패턴 ==== * p99 * Factory Method 패턴은 좋은 선택이 아니었다. 이번 장의 뒤에서 살펴볼 Strategy 패턴 등은 Factory Method 패턴의 멋진 대안이 된다. * 즉 아무도 필요하다고 요구하지 않은 부분까지 유연하다. 이와 같은 복잡도를 필요로 하는 시스템이 실제로 있을지는 모르겠지만, 스윙을 사용하다 보면 "왜 이정도의 유연성이 필요할까?" 라는 생각을 자주하게 되며, 또한 과도한 유연성으로 인한 복잡함이 별 이점 없이 개발 기간을 길게 만든다. ==== 깨지기 쉬운 기반 클래스 문제 정리 ==== * p101 * 여러분은 '꼼수'에 대한 생각할 필요가 없는 코드를 작성해야 하기 때문이다. * 프로그램을 정상적으로 동작하게 할 수 있는 꼼수를 발견했다면 뭐 그런대로 괜찮다. 하지만 내 주장의 핵심은 '''애초에 상속으로 인한 문제가 발생하지 않도록 했어야 한다는 것이다.''' * 그렇지.. - [서지혜] * p103 * 모든 선택에는 트레이드 오프가 있으며 해당 방법과 이를 대체할 수 있는 방법의 장점과 단점을 잘 헤아려 조율해야 할것이다. === 언제 extends를 사용해도 좋은가? === * p103 * 이제 언제 extends 관계를 사용해도 좋을지 논의해 보도록 하자. * 우선 클래스 정규화(데이터베이스 디자인에서 빌려온 용어이다)를 할 때 유용하게 사용할 수 있다. * 그렇군. 정규화 계층구조는 위에 있는 코드를 아래에서 써서 만드는거니까 상속을 이용하는게 편하다는거군? 예제 없나 근데? - [김준석] * 디자인을 하는 데 어떤 방법을 따르느냐는 결과에 큰 영향을 미친다. * p104 * 올바른 OO디자인은 다음과 같은 과정을 밟는다. * 여기 5개가 있는데 이것을 외워야 하는가!? - [김준석] * 동적 모델링으로부터 클래스 다이어그램을 도출하라. 이렇게 하면 실제 필요한 연산과 관계만이 포함되기 때문에 정적 모델이 현실적이 되고 가벼워진다. * 형진이가 지도해준 동적 모델링으로 우리가 하고있던 DB와 임상이 하는 SE를 모델링했을때는 참 재밌었지. 확실히. 내가 짠 프로그램보단 복잡도가 낮아보였어. 부럽. - [김준석] * p105 * 'is-a'는 그리 훌륭한 디자인 도구가 아니다. 우리가 늘 사용하는 자연어에 휘둘리지 말자. * 클래스 상속 기반 계층구조일때는 유용할듯 하지만. 우리가 원하는 extends를 제거하는 동적 디자인 시에는 그리 유용한 도구가 아닌것 같다. 'is-a'가 얼마나 날 잘못된 길로 이끌었던가! - [김준석] * 단순한 클래스 계층 구조는 복잡한 계층 구조보다 만들고 유지 보수하기 쉽다. 또한 인터페이스를 이용하여 구현 상속이 하는 것과 같은 작업을 수행할 수도 있다. * 음.. 확실히 이 책은 구현상속의 장점에대해 충분히 알아들어야지 extends의 장점에 대해 이해할수 있을것 같다. 이런경우가 어떤때인지 모르니까 - [김준석] * 상속한 메소드에서 예외를 던지지 말라. 즉 리스코프 대체 원칙(LSP)를 지키라. LSP를 어기면 다형성을 이용한 코딩을 할 수 없고, 결과적으로 개방 폐쇄의 원칙(OCP)도 지킬 수 없게 된다. * 기억해야할듯...? - [김준석] === extends 제거하기 === *p107 * 여러분이 시스템을 리팩토링하고 있다 가정해 보자. 차근차근 시작해보자. * 천리길도 한걸음부터. 이 부분이 2장의 알짜배기 같은데. 정말 길다. 그리고 재밌다. - [김준석] {{{ ~~java interface Employee { void youAreFired(); } }}} * 직원은 항상 해고될 준비를 해야한다. - [김준석] ==== 팩토리와 싱글톤 ==== *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 패턴 실체화이다. * 전역접근 이런게 많으면 관리하기 힘들다는거 아녀? - [김준석] ==== Singleton에서의 스레딩 이슈 ==== ==== Double-Checked Locking(사용하지 말라) ==== ==== Singleton 죽이기 ==== ==== Abstract Factory 패턴 ==== ==== 패턴 비빔밥 ==== ==== 팩토리를 이용한 동적 생성 ==== ==== Command 패턴과 Strategy 패턴 ==== === 요약 === == 라이프 게임 == === 라이프 얻기 === === 라이프 구조를 차트로 표현하기 === === Clock 서브시스템 : Observer 디자인 패턴 === ==== Observer 구현하기 : Publisher 클래스 ==== === Clock 서브시스템 : Visitor 패턴 === == 소형 데이터베이스 구현하기 == ---- [HolubOnPatterns], [DesignPatterns/2011년스터디]