이 글은 영상 처리(Image Processing)을 전공하고자 하는 사람들을 위해 개인적인 생각을 적은 글이다. 필자는 대학원에서 영상 처리를 전공으로 하였으며, 학부 또는 석사 과정에서 이런 책들을 진작에 잘 읽고 공부해놨으면 더 편하고 빠르게 많은 것들을 습득할 수 있지 않았을까 하는 생각을 해본다. 이 글을 읽는 대상은 대학원에서 영상 처리를 전공하고자 하는 학부 2~4학년 학생으로 생각하도록 하겠다.

1. Advanced Engineering Mathematics, 9/E

쉽게 말해 공업수학이다. 수학이야 말로 공학을 공부함에 있어 가장 기초적이면서도 중요한 과목이 아닐 수 없다. 특히, 공업수학은 공대생들을 위한 수학적 내용들을 공대생들이 접할 수 있는 예제를 이용하여 공대생들에게 필요한 방향으로 설명을 해놓았기 때문에 반드시 충실히 읽어야 할 책이라고 할 수 있다. 아마존( http://www.amazon.com/ )에 가서 Advanced Engineering Mathematics 으로 검색을 해보면 아마 다수의 저자에 의해 쓰여진 동일한 제목의 책들이 많은 것을 발견할 수 있을 것이다. 그 중에서 Erwin Kreyszig 의 책이 본교(한양대)에서 사용하고 있는 책으로써, 널리 사용되고 있는 책으로 알고 있다. 이미 9th edition이 나와있을 정도로 역사도 깊은 책이다. 이 외에도 필자는 Peter V. O'Neil 의 책도 소장하고 있는데, 이 책은 미분기하쪽에 대한 내용이 더 자세히 나와있다는 장점이 있다.

2. Linear Algebra and Its Applications, 3/E

Gilbert Strang 이라는 말을 좀 더듬는 MIT 교수님께서 쓰신 책이다. 영상(Image)이란 어차피 쉽게 생각하면 2차원 배열이다. 배열과 벡터의 속성에 대해서 공부하는 학문이 바로 선형 대수(linear algebra)라고 할 수 있다. 아마 학부 2~3학년 과정에서 배우지 않을까 하는 과목이다. 이 책과 더불어, 조금 쉬운 책 Introduction to Linear Algebra, 3/E 도 추천하고자 한다. 특히, 이 책은 MIT Open Lecture 라는 이름으로 인터넷을 통해 화상 강의를 볼 수 있다는 장점이 있다. 그러나, 어차피 내용은 Linear Algebra and Its Applications 책에도 다 있는 것들이므로, 굳이 Introduction to Linear Algebra 책을 구입해서 가지고 있을 필요까지는 없어보인다. 물론 수업은 영어로 진행되지만, 약간은 어눌하면서 빠르지 않게 말을 하기 때문에 한번 도전해보기를 적극 권장한다. 주소는 아래와 같다.

http://ocw.mit.edu/OcwWeb/Mathematics/18-06Spring-2005/CourseHome/

3. C++ 기초플러스 (5판)


영어 원서 제목은 C++ Primer Plus 이고, 저자는 Stephen Prata 이다. 영상 처리란 결국 프로그램을 작성하여 새로운 알고리즘을 테스트해보고 그 결과를 분석하는 작업이 주를 이룬다. 그렇다면, 무엇으로 프로그램을 작성할 것인가? Matlab, C, Java 등의 많은 프로그래밍 언어가 존재하지만, 역시 C++ 이 가장 믿음직한 언어가 아닐까 싶다. 필자가 한 때 java 로 영상 처리 프로그램을 해보긴 했지만 아무래도 대세가 아님을 실감했다. Matlab 은 그 결과를 신뢰할 수 있다는 장점이 있으나, 속도와 범용성, 상용성에서 떨어진다. 그렇다고 C 언어로 모든 것을 하는 시대는 이미 지났다. 이미 객체 지향 패러다임이 전반적으로 깔려있는 상태에서 C 만은 고집하는 것은 시대에 뒤떨어지겠다는 얘기를 하고 있는 것과 다르지 않다고 본다. C++ 이라고 해서 단순히 클래스와 상속성 개념을 이야기하는 것이 아니라, 템플릿과 STL을 같이 공부해야 한다. STL에 대해서는 따로 더 좋은 책들이 나와 있으니 참고하기 바란다. 어찌되었건, 이 책이야말로 C++ 을 다뤄야 하는 학생으로써 반드시 소장하고 있어야 할 책이 아닌가 싶다.

4. Numerical Methods for Engineers 4/E

Chapra 외 1명이 지은 책이다. 수치해석이란 수학적인 문제를 프로그래밍 형태로 푸는 방법을 소개한 책이다. 방정식의 해를 구하는 방법, 미분 혹은 적분을 하는 방법, 행열을 다루는 방법, 최대/최소값을 구하는 방법 등 공대에서 반드시 공부해야 할 학문 중의 하나이다. 아무리 뛰어난 이론을 생각해냈다고 하더라도, 실제로 구현하여 사용할 수 없다면 아무짝에도 소용없는 짓이 되어버린다(적어도 공대에서는...). 이 책에 나온 내용들은 가급적 직접 C++ 로 코딩하여야 확실하게 머리속에 남게 됨을 명심하자.

5. Digital Image Processing, 3/E


Gonzalez 외 2명이 같이 쓴 책이지만, 보통 곤잘레스 책이라고 한다. 영상 처리의 바이블이라고 해도 될만한 책으로, 이 책을 가지고 있지 않은 영상 처리 전공자는 없지 않을까 싶다. 사실, 이 책 말고도 많은 영상 처리 관련 책들이 존재하지만, 학부 과정에서 소화할 정도의 내용을 충실히 담은 책이기 때문에 교과서로 애용되고 있지 않은가 싶다. 2002년 2판이 나왔고, 2007년에 3판이 새로 나왔다. Digital Image Processing using Matlab 이라는 책도 같이 출간되었는데, 이 책은 그다지 권하고 싶지는 않다. 최근 한글 번역서도 출간되어있지만, 가급적 영어 원서로 공부하는 습관을 들이길 바란다.

6. Pattern Classification, 2/E


이 책의 저자는 Duda, Richard O. 외 2명이고, 보통 duda 책이라고 부르기도 한다. 이 책은 대학원 석사 과정 학생에게 권하고 싶은 책이다. 영상 처리라는 학문이 영상의 화질 개선(image enhancement), 영상 기술(description), 각종 필터링(low pass, high pass, etc) 등을 포함하면서 궁극적으로는 인식(recognition)으로 결론을 내지 않을까 싶다. 제목은 패턴 분류라고 되어있지만, 분류(classification)이라는 것은 결국 인식(recognition)으로 이어지게 된다. 이 책은 1973년 1판이 발행되서 거의 이 분야의 바이블로 여겨지다가, 2000년에 2판이 새로 나왔다. 

7. 영상 처리 프로그래밍 by Visual C++


이 책은 필자가 직접 집필한 책이며 영상 처리 이론뿐만이 아니라 구현에 대한 내용까지 담고 있다. 앞서 소개한 Digital Image Processing 에 나오는 영상 처리에 관한 기본적인 이론뿐만 아니라 비등방성 확산 필터(anisotropic diffusion filter), 해리스 코너 검출기(Harris corner detector), 전통적 레이블링 기법(traditional labeling) 등에 대한 설명과 코드를 수록하고 있다. 또한 BMP 파일 구조에 대한 상세한 설명과 OpenCV와 연동하는 방법 등도 유용하다. 윈도우즈 환경에서 Visual C++ 2005 와 MFC를 함께 사용하여 하나의 완성된 영상 처리 프로그램을 만드는 과정에 대해 알고싶다면 이 책을 강력히 추천한다. 다만, 프로그래밍이 완전히 초보인 사람들에게는 설명이 다소 어렵게 느껴질 수도 있다.

대충 중요한 책에 대해서는 언급을 한 것 같다. 이 외에도 좋은 책들이 많지만, 그것들을 다 나열하기는 힘들 것 같고, 적어도 위에서 언급한 책들은 당장 보지 않더라도 책장에 꽂아두고 언제든 참고할만한 가치가 있는 책들이다. 위의 7권 모두 학생판 형태로 5만원 안쪽으로 구입할 수 있는 책들이므로, 가급적 복사본 또는 번역본을 사지 말고 원서로 구입할 것을 추천한다.

공부 열심히 하세요~ ^^


펌글 : http://kkokkal.tistory.com/66


'생각하는개발 > 추천 개발도서' 카테고리의 다른 글

사고싶은책  (0) 2010.12.06
사랑하지 않으면 떠나라  (0) 2010.11.07
개발자가 놓치지 말아야 할 책 70권  (0) 2010.10.18
프로그래머의길, 멘토에게 묻다  (0) 2010.10.16
Code Complete 2  (0) 2010.10.16
Posted by 모과이IT
,

서른 다섯 지금 하지 않으면 반드시 후회하는 87가지
연봉 협상의 기술 : 연봉 협상 사장의 마음을 지배하라!
C++ How to Program : (한글판) (CD 1 포함)(제6판)
IT 개발자가 쓴 통쾌한 인간관리 이야기
잘 벌고 잘 쓰는 법 : 미국 100개 도시 최고 부자들이 말하는 부의 법칙
평생 살 안찌는 몸 만들기 : 아름다운 몸으로 다시 태어나는 23일 체질 성형 프로그램
누워서 읽는 알고리즘
최대리, 얘기 좀 할까 : 직장생활 10년차가 3년차에게 들려주는 직장인 생존 전략
서른과 마흔 사이 : 30대에 이루지 못하면 평생 후회하는 70가지
직장별종 탐구생활
Visual C++ 윈도우 스킨 & 테마프로그래밍 프로젝트 따라하기 : (CD 1 포함)
좋은 사람 콤플렉스
직장인의 운명은 30대에 결정된다

Posted by 모과이IT
,
메소드 정리
  • Extract Method(136) - 그룹으로 함께 묶을 수 있는 코드 조각이 있으면, 코드의 목적이 잘 드러나도록 메소드의 이름을 지어 별도의 메소드로 뽑아낸다.
  • Inline Method(144) - 메소드 몸체가 메소드의 이름 만큼이나 명확할 때는, 호출하는 곳에 메소드의 몸체를 넣고, 메소드를 삭제하라.
  • Inline Temp(146) - 간단한 수식의 결과값을 가지는 임시변수가 있고, 그 임시변수가 다른 리팩토링을 하는데 방해가 된다면, 이 임시변수를 참조하는 부분을 모두 원래의 수식으로 바꾸라.
  • Replace Temp with Query(147) - 어떤 수식의 결과값을 저장하기 위해서 임시변수를 사용하고 있다면, 수식을 뽑아내서 메소드로 만들고, 임시변수를 참조하는 곳을 찾아 모두 메소드 호출로 바꾼다. 새로 만든 메소드는 다른 메소드에서도 사용될 수 있다.
  • Introduce Explaining Variable(151) - 복잡한 수식이 있는 경우에는, 수식의 결과나 또는 수식의 일부에 자신의 목적을 잘 설명하는 이름으로 된 임시변수를 사용하라.
  • Split Temporary Variable(155) - 루프 안에 있는 변수나 collecting temporary variable도 아닌 임시변수에 값을 여러 번 대입하는 경우에는, 각각의 대입에 대해서 따로따로 임시변수를 만들어라.
  • Remove Assignments to Parameters(159) - 파라미터에 값을 대입하는 코드가 있으면, 대신 임시변수를 사용하도록 하라.
  • Replace Method with Method Object(163) - 긴 메소드가 있는데, 지역변수 때문에 Extract Method를 적용할 수 없는 경우에는, 메소드를 그 자신을 위한 객체로 바꿔서 모든 지역변수가 그 객체의 필드가 되도록 한다. 이렇게 하면 메소드를 같은 객체 안의 여러 메소드로 분해할 수 있다.
  • Substitute Algorithm(167) - 알고리즘을 보다 명확한 것으로 바꾸고 싶을 때는, 메소드의 몸체를 새로운 알고리즘으로 바꾼다.

객체간의 기능 이동
  • Move Method(170) - 메소드가 자신이 정의된 클래스보다 다를 클래스의 기능을 더 많이 사용하고 있다면, 이 메소드를 가장 많이 사용하고 있는 클래스에 비슷한 몸체를 가진 새로운 메소드를 만들어라. 그리고 이전 메소드는 간단한 위임으로 바꾸거나 완전히 제거하라.
  • Move Field(175) - 필드가 자신이 정의된 클래스보다 다른 클래스에 의해서 더 많이 사용되고 있다면, 타겟 클래스(target class)에 새로운 필드를 만들고 기존 필드를 사용하고 있는 모든 부분을 변경하라.
  • Extract Class(179) - 두 개의 클래스가 해야 할 일을 하나의 클래스가 하고 있는 경우, 새로운 클래스를 만들어서 관련 있는 필드와 메소드를 예전 클래스에서 새로운 클래스로 옮겨라.
  • Inline Class(184) - 클래스가 하는 일이 많지 않은 경우에는, 그 클래스에 있는 모든 변수와 메소드를 다른 클래스로 옮기고 그 클래스를 제거하라.
  • Hide Delegate(187) - 클라이언트가 객체의 위임 클래스를 직접 호출하고 있는 경우, 서버에 메소드를 만들어서 대리객체(delegate)를 숨겨라.
  • Remove Middle Man(191) - 클래스가 간단한 위임을 너무 많이 하고 있는 경우에는, 클라이언트가 대리객체(delegate)를 직접 호출하도록 하라.
  • Introduce Foreign Method(194) - 사용하고 있는 서버 클래스에 부가적인 메소드가 필요하지만 클래스를 수정할 수 없는 경우에는, 첫 번째 인자로 서버 클래스의 인스턴스를 받는 메소드를 클라이언트에 만들어라.
  • Introduce Local Extension(196) - 사용하고 있는 서버 클래스에 여러 개의 메소드를 추가할 필요가 있지만 서버 클래스를 수정할 수 없는 경우, 필요한 추가 메소드를 포함하는 새로운 클래스를 만들어라. 이 확장 클래스를 원래 클래스의 서브클래스 또는 래퍼(wrapper) 클래스로 만들어라.

데이터 구성
  • Self Encapsulate Field(205) - 필드에 직접 접근하고 있는데 필드에 대한 결합이 이상해지면, 그 필드에 대한 get/set 메소드를 만들고 항상 이 메소드를 사용하여 필드에 접근하라.
  • Replace Data Value with Object(209) - 추가적인 데이터나 동작을 필요로 하는 데이터 아이템이 있을 때는, 데이터 아이템을 객체로 바꾸어라.
  • Change Value to Reference(213) - 동일한 인스턴스를 여러 개 가지고 있는 클래스가 있고 여러 개의 동일한 인스턴스를 하나의 객체로 바꾸고 싶으면, 그 객체를 참조 객체로 바꾸어라.
  • Change Reference to Value(217) - 작고, 불변성(immutable)이고, 관리하기가 어려운 참조 객체(reference object)가 있는 경우, 그것을 값 객체(value object)로 바꾸어라.
  • Replace Array with Object(220) - 배열의 특정 요소가 다른 뜻을 가지고 있다면, 배열을 각각의 요소에 대한 필드를 가지는 객체로 바꿔라.
  • Duplicate Observed Data(224) - GUI 컨트롤에서만 사용 가능한 도메인 데이터가 있고, 도메인 메소드에서 접근이 필요한 경우, 그 데이터를 도메인 객체로 복사하고, 옵저버(observer)를 두어 두 데이터를 동기화하라.
  • Change Unidirectional Association to Bidirectional(232) - 각각 서로의 기능을 필요로 하는 클래스가 있는데, 링크가 한쪽 방향으로만 되어 있는 경우, 반대 방향으로 포인터를 추가하고, 수정자(modifier)가 양쪽 세트(set)를 모두 업데이트 하게 변경하라.
  • Change Bidirectional Association to Unidirectional(236) - 서로 링크를 가지는 두 개의 클래스에서 한 쪽이 다른 한쪽을 더 이상 필요로 하지 않을 때는 불필요한 링크를 제거하라.
  • Replace Magic Number with Symbolic Constant(240) - 특별한 의미를 가지는 숫자 리터럴이 있으면, 상수를 만들고, 의미를 잘 나타내도록 이름을 지은 다음, 숫자를 상수로 바꾸어라.
  • Encapsulate Field(242) - public 필드가 있는 경우, 그 필드를 private으로 만들고, 접근자를 제공하라.
  • Encapsulate Collection(244) - 컬렉션(Collection)을 리턴하는 메소드가 있으면, 그 메소드가 읽기전용 뷰(read-only view)를 리턴하도록 만들고, add/remove 메소드를 제공하라.
  • Replace Record with Data Class(254) - 전통적인 프로그래밍 환경에서의 레코드 구조에 대한 인터페이스가 필요한 경우, 그 레코드를 위한 데이터 객체를 만들어라.
  • Replace Type Code with Class(255) - 클래스의 동작에 영향을 미치지 않는 숫자로 된 타입 코드(numeric type code)가 있으면, 숫자를 클래스로 바꾸어라.
  • Replace Type Code with Subclass(261) - 클래스의 동작에 영향을 미치는 변경 불가능한(immutable) 타입 코드가 있다면, 타입 코드를 서브클래스로 바꾸어라.
  • Replace Type Code with State/Strategy(265) - 클래스의 동작에 영향을 미치는 타입 코드가 있지만 서브클래싱을 할 수 없을 때는, 타입 코드를 스테이트(State) 객체로 바꾸어라.
  • Replace Subclass with Fields(270) - 상수 데이터를 리턴하는 메소드만 다른 서브클래스가 있으면, 그 메소드를 수퍼클래스의 필드로 바꾸고 서브클래스를 제거하라.

조건문의 단순화
  • Decompose Conditional(276) - 복잡한 조건문(if-then-else)이 있는 경우, 조건, then 부분, 그리고 else 부분에서 메소드를 추출하라.
  • Consolidate Conditional Expression(278) - 같은 결과를 초래하는 일련의 조건 테스트가 있는 경우, 그것을 하나의 조건 식으로 결합하여 뽑아내라.
  • Consolidate Duplicate Conditional Fragments(281) - 동일한 코드 조각이 조건문의 모든 분기 안에 있는 경우, 동일한 코드를 조건문 밖으로 옮겨라.
  • Remove Control Flag(283) - 일련의 boolean 식에서 컨트롤 플래그 역할을 하는 변수가 있는 경우, break 또는 return 을 대신 사용하라.
  • Replace Nested Conditional with Guard Clauses(288) - 메소드가 정상적인 실행 경로를 불명확하게 하는 조건 동작을 가지고 있는 경우, 모든 특별한 경우에 대해서 보호절(guard clause)을 사용하라.
  • Replace Conditional with Polymorphism(293) - 객체의 타입에 따라 다른 동작을 선택하는 조건문을 가지고 있는 경우, 조건문의 각 부분을 서브클래스에 있는 오버라이딩 메소드로 옮겨라. 그리고 원래 메소드를 abstract로 만들어라.
  • Introduce Null Object(298) - null 체크를 반복적으로 하고 있다면, null 값을 null 객체로 대체하라.
  • Introduce Assertion(306) - 코드의 한 부분이 프로그램의 상태에 대하여 어떤 것을 가정하고 있으면, assertion을 써서 가정을 명시되게(explicit) 만들어라.

메소드 호출의 단순화
  • Rename Method(313) - 메소드의 이름이 그 목적을 드러내지 못하고 있다면 메소드의 이름을 바꿔라.
  • Add Parameter(316) - 어떤 메소드가 그 메소드를 호출하는 부분에서 더 많은 정보를 필요로 한다면, 이 정보를 넘길 수 있는 객체에 대한 파라미터를 추가하라.
  • Remove Parameter(318) - 파라미터가 메소드 몸체에서 더 이상 사용되지 않는다면, 그 파라미터를 제거하라.
  • Separate Query from Modifier(320) - 값을 리턴할 뿐만 아니라 객체의 상태도 변경하는 메소드를 가지고 있는 경우, 두 개의 메소드를 만들어서 하나는 값을 리턴하는 역할을 하고, 하나는 객체의 상태를 변경하는 역할을 하게 하라.
  • Parameterize Method(325) - 몇몇 메소드가 메소드 몸체에 다른 값을 포함하고 있는 것을 제외하고는 비슷한 일을 하고 있다면, 다른 값을 파라미터로 넘겨 받는 하나의 메소드를 만들어라.
  • Replace Parameter with Explicit Methods(327) - 파라미터의 값에 따라서 다른 코드를 실행하는 메소드가 있다면, 각각의 파라미터 값에 대한 별도의 메소드를 만들어라.
  • Preserve Whole Object(331) - 어떤 객체에서 여러 개의 값을 얻은 다음 메소드를 호출하면서 파라미터로 넘기고 있다면, 대신 그 객체를 파라미터로 넘겨라.
  • Replace Parameter with Method(335) - 객체가 메소드를 호출한 다음, 결과를 다른 메소드에 대한 파라미터로 넘기고 있다. 수신자(Receiver - 파라미터를 넘겨 받는 메소드) 또한 이 메소드를 호출할 수 있다면, 그 파라미터를 제거하고 수신자가 그 메소드를 호출하도록 하라.
  • Introduce Parameter Object(339) - 자연스럽게 몰려다니는 파라미터 그룹을 가지고 있다면, 그것들을 객체로 바꾸어라.
  • Remove Setting Method(344) - 어떤 필드가 객체 생성시에 값이 정해지고 그 이후에는 변경되지 않아야 한다면, 그 필드 값을 설정하는 모든 메소드를 제거하라.
  • Hide Method(348) - 메소드가 다른 클래스에서 사용되지 않는다면, 그 메소드를 private으로 만들어라.
  • Replace Constructor with Factory Method(350) - 객체를 생성할 때 단순히 생성하는 것 이외에 다른 작업도 하고 있다면, 생성자를 팩토리 메소드로 대체하라.
  • Encapsulate Downcast(355) - 메소드가 그 호출부에서 다운캐스트(downcast) 될 필요가 있는 객체를 리턴하고 있다면, 다운캐스트 하는 것을 메소드 안으로 옮겨라.
  • Replace Error Code with Exception(357) - 메소드가 에러를 나타내는 특별한 코드를 가지고 있다면, 대신 예외를 던져라.
  • Replace Exception with Test(363) - 호출부에서 먼저 검사할 수 있는 조건에 대해 예외를 던지고 있다면, 호출부가 먼저 검사하도록 바꿔라.

일반화 다루기
  • Pull Up Field(368) - 두 서브클래스가 동일한 필드를 가지고 있다면, 그 필드를 수퍼클래스로 옮겨라.
  • Pull Up Method(370) - 동일한 일을 하는 메소드를 여러 서브클래스에서 가지고 있다면, 이 메소드를 수퍼클래스로 옮겨라.
  • Pull Up Constructor Body(373) - 서브클래스들이 대부분 동일한 몸체를 가진 생성자를 가지고 있다면, 수퍼클래스에 생성자를 만들고 서브클래스 메소드에서 이것을 호출하라.
  • Push Down Method(376) - 수퍼클래스에 있는 동작이 서브클래스 중 일부에만 관련되어 있다면, 그 동작을 관련된 서브클래스로 옮겨라.
  • Push Down Field(377) - 어떤 필드가 일부 서브클래스에 의해서만 사용되고 있다면, 그 필드를 관련된 서브클래스로 옮겨라.
  • Extract Subclass(378) - 어떤 클래스가 일부 인스턴스에 의해서만 사용되는 기능을 가지고 있다면, 기능의 부분집합을 담당하는 서브클래스를 만들어라.
  • Extract Superclass(384) - 비슷한 메소드와 필드를 가진 두 개의 클래스가 있다면, 수퍼클래스를 만들어서 공통된 메소드와 필드를 수퍼클래스로 옮겨라.
  • Extract Interface(389) - 여러 클라이언트가 한 클래스 인터페이스의 동일한 부분 집합을 사용하고 있거나, 두 클래스가 공통된 인터페이스를 가지는 부분이 있다면, 그 부분 집합을 인터페이스로 뽑아내라.
  • Collapse Hierarchy(392) - 수퍼클래스와 서브클래스가 별로 다르지 않다면, 그것들을 하나로 합쳐라.
  • Form Template Method(393) - 각각의 서브클래스에, 동일한 순서로 비슷한 단계를 행하지만 단계가 완전히 같지는 않은 두 메소드가 있다면, 그 단계를 동일한 시그니처를 가진 메소드로 만들어라. 이렇게 하면 원래의 두 메소드는 서로 같아지므로, 수퍼클래스로 올릴 수 있다.
  • Replace Inheritance with Delegation(401) - 서브클래스가 수퍼클래스 인터페이스의 일부분만 사용하거나 또는 데이터를 상속 받고 싶지 않은 경우, 수퍼클래스를 위한 필드를 만들고 메소드들이 수퍼클래스에 위임하도록 변경한 후 상속 관계를 제거한다.
  • Replace Delegation with Inheritance(404) - 위임을 사용하고 있는데, 전체 인터페이스에 대해 간단한 위임을 자주 작성하고 있다면, 위임하는 클래스를 대리객체의 서브클래스로 만들어라.

대규모 리팩토링
  • Tease Apart Inheritance(410) - 두 가지 작업을 한번에 처리하는 상속 구조가 있는 경우, 두개의 상속 구조를 만들고 하나가 다른 하나를 호출하도록 위임을 사용하라.
  • Convert Procedural Design To Objects(416) - 절차적 스타일로 작성된 코드가 있다면, 데이터 레코드를 객체로 바꾸고, 동작을 쪼개서 객체로 옮겨라.
  • Separate Domain from Presentation(418) - 도메인 로직을 포함하고 있는 GUI 클래스를 가지고 있다면, 도메인 로직을 분리하여 도메인 클래스를 만들어라.
  • Extract Hierarchy(423) - 너무 많은 작업을 하거나 또는 부분적으로라도 많은 조건문이 있는 클래스에 대해서는, 각각의 서브클래스가 특정 작업을 담당하도록 클래스의 상속 구조를 만들어라.

'생각하는개발 > 리팩토링' 카테고리의 다른 글

리팩토링 기술 업그레이드 하기  (0) 2010.09.27
Form Template Method  (0) 2010.09.27
Extract Super Class  (0) 2010.09.27
Introduce Parameter Object  (0) 2010.09.27
Extract Class  (0) 2010.09.27
Posted by 모과이IT
,

추상 팩토리 패턴
서로 연관된 또는 의존적인 객체들로 이루어진 제품군을 생성하기 위한
인터페이스를 제공한다. 구상 클래스는 서브 클래스에 의해 만들어진다.

추상 팩토리 패턴 예제
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace::std;

class CAudio
{
public:
 virtual void Run() = 0;
};

class CWindowAudio : public CAudio
{
public:
 virtual void Run()
 {
  cout << "Window Audio Run" << endl;
 }
};

class CUnixAudio : public CAudio
{
public:
 virtual void Run()
 {
  cout << "Unix Audio Run" << endl;
 }
};

class CVideo
{
public:
 virtual void Run() = 0;
};

class CWindowVideo : public CVideo
{
public:
 virtual void Run()
 {
  cout << "Window Video Run" << endl;
 }
};

class CUnixVideo : public CVideo
{
public:
 virtual void Run()
 {
  cout << "Unix Video Run" << endl;
 }
};


class COSFactory
{
public:
 virtual CAudio* CreateAudio() = 0;
 virtual CVideo* CreateVideo() = 0;
};

class CWindowFactory : public COSFactory
{
public:
 virtual CAudio* CreateAudio(){ return new CWindowAudio; }
 virtual CVideo* CreateVideo(){ return new CWindowVideo; }
};

class CUnixFactory : public COSFactory
{
public:
 virtual CAudio* CreateAudio(){ return new CUnixAudio; }
 virtual CVideo* CreateVideo(){ return new CUnixVideo; }
};

void main()
{
 COSFactory* pOSFactory = new CWindowFactory;

 CVideo* pVideo = pOSFactory->CreateVideo();
 CAudio* pAudio = pOSFactory->CreateAudio();

 pVideo->Run();
 pAudio->Run();

 delete pVideo;
 delete pAudio;

 delete pOSFactory;
}

==========================================================================================================


첫 강좌를 쓰고 나니 왠지 굉장히 귀찮아 지는군요. 역시 게으른 자는 이래서 안된다니까.. >.<   그래서 '괜히 패턴을 8개나 소개한다고 했구나..' 하고 후회하고 있던 중에 이 강좌를 봐주시는 분이 있다라는 것을 알고 좀 부지런 해지기로 했습니다. 

암튼 읽어주시는 분들께는 감솨를 드립니다. ㅠ_ㅠ

 그리고 깜빡하고 말씀 안드린 것이 있는데, 디자인 패턴은 언어에 독립적입니다.  여기서 C++을 써서 구현을 했지만 다른 모든 언어에서 구현이 가능하다고 합니다. 심지어 기존의 C로도 구현이 가능하다고 합니다. 저는 C++밖에 모르기 때문에 '어떻게 다른 언어로 구현하느냐'라고 묻지는 마세요.

< Abstract Factory >
'추상적인 공장' 이라고 해석해야 하나? 암튼 그런 뜻입니다. 
객체 지향에서는 abstract(추상적인)이라는 말과 concrete(구체적인)라는 말이 자주 쓰이는데, 클래스 상속에서 상대적인 개념을 나타낼 때 주로 쓰입니다.  소녀라는 클래스가 사람이라는 클래스를 상속했을 때 소녀 concrete 클래스라고 부르고 사람을 abstract 클래스라고 부릅니다. 이것은 우리가 실 생활에서 개념을 다루는 방식과 비슷합니다.  우리가 사람이라는 개념이 소녀라는 개념보다 추상적인 개념이고, 소녀라는 개념이 사람 이라는 개념보다 구체적이다라고 말하는 것과 같습니다.  또한 실 생활에서 처럼 추상적인 클래스와 구체적인 클래스는 상대적인 개념이지요.  사람은 소녀에 비해 추상적인 개념이지만 동물이라는 개념에 비해서는 구체 적인 개념이지요.  이처럼 사람 클래스와 동물 클래스가 있다면 사람 클래스가 구체적인 클래스(concrete)가 되고 동물 클래스가 추상적인 클래스(abstract)가 되는 것입니다.

<의도>
 구체적인 클래스들을 지정하지 않고 연관되어 있는 객체들의 패밀리를 생성하는 인터페이스를 제공하고 싶다.
 책을 직역하니 대충 이런 내용이 되는군요.  이해가 안 가시리라 믿습니다. -_-;;

<동기>
 스타크래프트를 개발하는 상황을 상상해 봅시다.  빌 로퍼가 배를 내밀며 지시를 내립니다. "세 종족 모두 서로 다른 독특한 건물을 가지게 할것이고, 인터페이스는 모두 통일을 하게 만들어야 하느니라~~  알겠느뇨~~"  당신이 묻는다.  "왜 세 종족 모두 독특한 건물을 가져야 합니까?"  "재밌으니까!!!" 빌이 대답한다. 당신이 또 묻는다. "그럼 왜 인터페이스는 통일시켜야만 합니까?"  "인터페이스를 통일시키면 프로그래밍을 하기 편하니까!!" 라고 빌은 또 대답한다.  당신은 또 묻는다.  "그렇지만 인터페이스를 통일시키는 작업은 쉽지 않쟎습니까?"  그러자 빌이 인상을 찌뿌리며 말한다. "쟤네들(인공지능 프로그래머)이 몸이 쫌 약하자나~~  니가 쫌 고생해라~~ 잉?" 

(... 이것이 게임회사의 현실입니다.. -_-;; )

당신은 이제 각기 다른 건물 구성을 가진 세 종족의 인터페이스를 통일시키지 않으면 빌의 배치기에 목숨을 잃을 판입니다. 

 이것에 대한 좋은 해결책이 이 패턴입니다.  이 패턴은 객체들을 생성하는 것과 사용하는 것을 분리시켜서 그 객체의 내용(구현)에 신경을 쓰지 않고 객체를 사용할 수 있도록 해줍니다.  결국에 이것은 인터페이스와 구현을 분리시키게 되는 것입니다. 

 이제 빌의 배치기에 위협당하는 상황으로 돌아가봅시다.  당신이 어쩔 수 없는 상황에 부처님께 기도를 드리자 부처님이 당신의 꿈에 나타나 계시를 내려 주십니다.  "너의 정성이 갸륵하여 인터페이스 클래스라는 것을 알려 주겠노라!!"     할렐루야~~

class cUnit
{
public:
    virtual void Attack() = 0;      //반드시 재정의 해야함
    virtual void Move() = 0;
    virtual void Stop() = 0;
    virtual void HoldPosition() = 0;   

    virtual void Special1() {}      //재정의 안해도 됨
    virtual void Special2() {} 
};

class cZealot : public cUnit
{
public:
    void Attack(); 
    void Move();
    void Stop();
    void HoldPosition();
};
 

 이것이 인터페이스 클래스입니다.. 먼저 순수 가상함수를 눈여겨 보세요

    virtual cUnit * Create1stUnit() = 0;

이것이 순수가상함수입니다..  뒤에 = 0; 이 붙이있는 것을 보고 의아하게 생각 하시겠지만 이것은 0을 대입한다는 뜻이 아니라 구현이 없다는 뜻입니다.  이 순수 가상함수가 하나라도 있는 클래스는 인스턴스를 생성할 수 없고 순수 가상 함수를 포함한 클래스를 상속한 클래스는 순수 가상 함수들을 모두 재정의 해야만 인스턴스를 생성할 수 있습니다. 저 늠름한 질럿 클래스를 보시면 Attack함수부터 HoldPosition까지 4개 모두를 재정의한 것을 알 수 있습니다.  때문에 Zealot 클래스는 인스턴스를 생성할 수 있지만 cUnit은 인스턴스를 생성할 수 없습니다.  만약 cZealot에서 4개의 순수 가상 함수 중 하나라도 빼먹고 재정의 하지 않았다면 컴파일러가 에러를 일으키기 때문에 cZealot의 인스턴스도 생성할 수 없게 됩니다..  순수 가상 함수는 실제 함수가 아닌 인터페이스에 대한 약속이라고 보면 됩니다.  순수 가상 함수에 대해 설명을 하다 보면 끝이 없으니 C++ 비급을 보고 열심히 연마하시길 바랍니다.
 

 또 알아햐 할 것은 다형성입니다.  설명을 위해 하이템플러를 추가하겠습니다.

class cHiTemplar : public cUnit
{
public:
    void Attack();
    void Move();
    void Stop();
    void HoldPosition();
    void Special1();
    void Special2();        //하이템플러는 마법이 세개였나?
                            //귀찮아서 두개만...
};

cZealot zealot;
cHiTemplar templar;

cUnit * Unit1 = &zealot;
Unit1->Attack();            //zealot.Attack()와 같은 결과

Unit1 = &templar;
Unit1->Attack();            //templar.Attack()와 같은 결과

 이것이 다형성입니다.  Unit1에 들어간 클래스형에 따라 그 클래스형에 맞는 함수가 호출되는 것을 알 수 있을 것입니다.  이것 역시 자세한 것은 C++비급을 참고하세요.

 이 인터페이스 클래스는 인터페이스와 구현을 확실히 분리시켜 주기 때문에 유닛을 사용에 대한 프로그래밍 할 때 유닛이 무엇인지 신경 쓸 필요도 없게 해줍니다.  또한 이것으로 인해 모든 유닛들을 큐나 리스트, 트리 등의 자료구조로 다룰 수 있게 되는 이점도 있습니다.

 또 다른 이점은 사용할 때에는 인터페이스 클래스만 include 해주면 되기 때문에 컴파일 연관성을 줄여주고 컴파일을 빠르게 해준다는 것입니다. 
 
 이제 Abstract Factory의 핵심을 설명하는 것이 남았습니다.
Abstract 클래스의 핵심은 생성하는 것과 사용하는 것의 분리와 객체 패밀리의 지정입니다.

class cPrimaryFactory               //1차 생산건물에 대한
{                                   //인터페이스 클래스
public:
    virtual cUnit * CreateUnit1() = 0;
    virtual cUnit * CreateUnit2() = 0;
    virtual cUnit * CreateUnit3() = 0;
    virtual cUnit * CreateUnit4() = 0;

    //베이스 클래스의 소멸자는 virtual이어야 합니다.
    //Effective C++참조.
    virtual ~cPrimaryFactory();    
};

class cBarrack : public cPrimaryFactory
{
public:
    cUnit * CreateUnit1()   { return new cMarine; }
    cUnit * CreateUnit2();  { return new cFirebat; }
    cUnit * CreateUnit3();  { return new cGhost; }
    cUnit * CreateUnit3();  { return new cMedic; }

};

 여기서 CreateUnit함수들의 구현을 단순히 [return new 유닛] 이렇게 해놨는데, 실제로는 이렇게 단순하지 않을 것입니다.  메모리 유출을 피하기 위해 먼저 Object Manager같은 클래스에 포인터를 저장하고 난 다음에 리턴하던지 하겠죠.

class cGateway : public cPrimaryFactory
{
public:
    cUnit * CreateUnit1();          //질럿 생산
    cUnit * CreateUnit2();          //드래군
    cUnit * CreateUnit3();          //하이템플러
    cUnit * CreateUnit4();          //다크템플러
};

class cHatchery : public cPrimaryFactory
{
public:
    cUnit * CreateUnit1();          //저글링
    cUnit * CreateUnit2();          //히드라
    cUnit * CreateUnit3();          //???
    cUnit * CreateUnit4();          //???
};

 저그의 해처리는 특이한 구조이기 때문에 다른 패턴을 동원해야 합니다만 설명을 위해 단순화하기로 하겠습니다.  UML도표를 그려서 설명하면 쉬운데.. 힘들군요.  뭐~ 이 강좌는 어디까지나 소개 차원에서 하는 것이므로 실제로 이 패턴들을 써서 프로그래밍을 하고 싶으신 분은 디자인 패턴 책을 반드시 사시길 바랍니다.  이미 패턴을 모두 알고 있다 해도 디자인 패턴 책은 패턴 사전으로서의 가치가 크기 때문에 프로그래밍 할 때
반드시 참고하시길..

 위의 PrimaryFactory를 상속한 클래스들이 Abstract Factory 들입니다. 

cPrimaryFactory * Factory1st = UI.GetUserFactory1();
                                //유저가 현재 선택한 종족의
                               //첫번째 생산 공장에 대한 포
                               //인터를 얻어옵니다.

//첫번째 유닛 생산 명령이 떨어졌을 경우
Factory1st->CreateUnit1(); 
//세번째 유닛 생산 명령이 떨어졌을 경우
Factory1st->CreateUnit3();

 이렇게 사용하면 되는 것입니다.  인터페이스가 통일 되었기 때문에 공장이 어느 종족의 것인지, 유닛이 구체적으로 어떤 종류의 것인지 신경을 쓸 필요가 없게 되었습니다. 만약 이 패턴을 쓰지 않고 만든다면 if문을 이용해서 세 종족의 경우를 모두 코딩 해주어야 할 것입니다.  코딩의 비용이 3배나 늘어나게 되는 셈이지요.  게다가 구조가 바뀌었을 때 3배나 되는 코드를 수정해야 하므로 유지보수 비용도 3배가 되는 셈입니다.  그러나 실제로는 3배가 훨씬 넘는다고 할 수 있습니다.  이 패턴을 쓰면 구현과 인터페이스를 분리시키기 때문에 함수 하나의 구현이 바뀐다고해서 인터페이스를 바꿀 필요도 없을 뿐더러 대부분의 경우 바뀌는 부분이 그 함수 하나 뿐일 경우가 많습니다.  그러나 if를 이용한 구조적 프로그래밍의 경우에는 함수 구현이 조금만 바뀌어도 연쇄적으로 수정해야 할 부분이 생기는 경우가 흔합니다. 

 이 패턴에서 객체의 생성과 사용을 분리시키는 이유는 인터페이스와 구현의 분리를 위해서라고 말씀 드렸습니다. 객체의 생성은 구현에 종속적일 수밖에 없는데 그 이유는 생성자에서 객체의 값을 할당하는 등의 설정을 하기 때문입니다.  객체의 생성이 단순히 new Object를 하는 것만을 의미하지는 않고, Object에 각종 설정을 하는 것을 모두 포함합니다.  Bitmap클래스라면 new Bitmap을 해서 클래스를 만들고 비트맵을 로딩하고, 필요한 만큼 잘라내는 등등 사용하기 전에 세팅하는 것을 모두 포함하는 것입니다.  우리가 컴퓨터를 사용하듯이 말입니다.  컴퓨터 부품들을 새로 사서 조립을 하고 세팅을 하는 과정은 부품들에 따라 약간씩 다릅니다.  많이 다른 경우도 있지요.  그렇지만 일단 세팅을 다 끝내고 사용하는 것은 다 같습니다. 

<적용>
이럴 때 Abstract Factory 패턴을 사용하라는군요

- 시스템이 그것의 컴포넌트들이 어떻게 생성되고 조립되고 표현되는지(사용되는지)와 독립적이어야 할 때.
- 시스템이 다양한 컴포넌트의 패밀리 중 하나로 설정되어야 할 때
- 관련된 컴포넌트들의 패밀리가 함께 쓰여야 하도록 디자인 되었고, 이런 구속을 강제해야만 할 때
- 클래스 라이브러리를 제공 하려는데 그것의 구현을 드러내지 않고 인터페이스만 드러내길 원할 때

<맺음말>
 어쩌다 보니 인터페이스 클래스와 abstract Factory패턴, Factory Method패턴까지 섞여버렸습니다.  원래 디자인 패턴에서는 디자인 시의 의사소통을 위해 패턴들의 개념을 명확히 구분하는데, 이 강좌의 목적은 어디까지나 소개이므로 '디자인 패턴은 좋은 것이다!'라는 것에 초점을 맞추어 설명을 했습니다. 계속 강조하지만 디자인 패턴을 실제로 써먹으실 분들은 책을 사서 제대로 공부하시길 바랍니다. 

p.s 원래는 factory method 패턴을 따로 하려고 했는데 위에 포함이 되었으므로 따로 하지 않겠습니다.  위에서 객체의 생성을 함수에 몰아넣고 하는 것이 factory method 패턴입니다. 그리고 factory method들을 묶어놓는 것이 abstract factory 입니다.
 
p.s 예전에 C&C를 좋아하며 Rule을 에디트하는 에디터를 받아서 열심히 했던 적이 있었습니다.  저 에디터를 써보신 분은 알겠지만 C&C에서는 유닛들이 부품들로 이루어져 있고, 스크립트를 통해 부품 조합을 새로 함으로써 MOD를 만들 수 있도록 해놓았습니다. 탱크같으면 포는 레이저포, 장갑은 특수 티타늄 장갑, 이동장치는 탱크바퀴 등등 이런 식으로 객체가 나뉘어져 있습니다. 이런 것을 구현할 때에도 이 abstract factory 패턴은 아주 유용합니다. 인터페이스를 통일해 버리기 때문에 프로그래밍 부분에서는 그 부품이 어떤 것인지는
신경을 쓸 필요가 없습니다.  단지 인터페이스를 갖고 놀면서 프로그래밍을 하면 되는 것이지요.  반면에
이 패턴을 쓰지 않으면 if문을 남발한 하드 코딩을 하게 될 것입니다.  더  좋은 방법을 생각해 낸다 하더라도
이 패턴을 이용하는 것만 큼 많은 이점을 가지기는 힘들 겠지요.  잘 쓰시기 바랍니다.

Posted by 모과이IT
,
Posted by 모과이IT
,

코딩 스타일의 상식을 박살 내라


 

서두

엔지니어 여러분은 평상시 다양한 상식에 사로 잡히고 있지 않습니까? 그러한 상식의 상당수는 믿음이며 당신의 능력이나 생산성을 방해하는 요인이 되고 있습니다. 이 연재에서는 고정 관념을 깨어, 유저 시점에서 고품질의 일을 해내는 「리얼 엔지니어」으로 한 걸음을 내디디는 아이디어 여러 가지를 소개합니다.


빠져 나가라! 영문법의 속박

베테랑일수록 「그래, 이러한 것」적인 미를 고집하는 것 같습니다.

예를 들면 프로그램 언어는 영어를 기조로 하고 있습니다.「영문법을 의식하는 것이 아름답다. 왜냐하면 그러한 것이니까」라고 하는 것은 그 대표 예입니다.

우선 이 예를 봐 주세요. 직감적으로 어느 쪽이 아름다운지 아이와 같은 깨끗한 마음으로 봐 주세요.

 

예 A

  1. TopMargin = 10;

  2. BottomMargin = 10;

  3. LeftMargin = 20;

  4. RightMargin = 20;

 

예 B

  1. MarginTop = 10;

  2. MarginBottom = 10;

  3. MarginLeft = 20;

  4. MarginRight =20;

 

 A는 영문법에 따른 기술, 예 B는 Margin을 앞으로 기술했습니다.

어떻습니까?

영문법을 무시한 예 B쪽이 「Margin」이 깨끗하게 갖추어져 있어 아름답지 않습니까. 여기까지 깨끗하게 모이면 대입 부분 「
= 10;
」도 정리하고 싶어집니다.

 

예 C

  1. MarginTop    = 10;

  2. MarginBottom = 10;

  3. MarginLeft   = 20;

  4. MarginRight  = 20;

 

한층 더 아름다워졌습니다. 소스의 시인성(視認性)이 올라서 유지보수도 편하게 되겠죠.

 

보충

최근에는 클래스로 설계하므로,

Margin->Top = 10;

라고 기술하는 것이 많습니다만 네이밍이라고 하는 시점에서 읽어 주세요.

 

상식에 속박 되고 있지 않습니까? 「있어야 아름다운 모습」이라고 생각하고 있는 것은 정말로 아름답습니까?


 


훌륭한 멀티 스테이트먼트의 세계!

「멀티 스테이트먼트」. 이 단어를 알고 있는 분, 기억하고 있는 분, 어느 정도 계십니까?  80년대 전반 주로 interpreter 언어에 있어서 유행된 기술 방법입니다.

 

멀티 스테이트먼트란

지금은

  1. a=10;

  2. b=20;

  3. c=a+b;

  4.  

 

이라고 쓰는 것을

  1. a=10; b=20; c=a+b;

 

와 같이 쓰는 것이 멀티 스테이트먼트입니다. 1행에  복수의 명령을 기술하는 매우 기분 나쁜 기술 방법입니다.

그렇지만 옛날에는 제대로 의미가 있었습니다. 아직 컴퓨터가 빈약했던 시대 멀티 스테이트먼트로 기술하는 것으로

  조금 메모리가 절약

  좀 더 처리 스피드가 오른

닙다.

그 후 컴퓨터 기술의 발달에 의해 멀티 스테이트먼트는 그 의미를 잃었습니다…….

 

부활! 현대풍 멀티 스테이트먼트!

우선 다음의 소스를 봐 주세요. 월 마다 대입 문자열을 바꾸는 처리로 비교적 알기 쉬운 소스입니다.

 

  1. switch(month){

  2.     case 1:

  3.        tsuki="1월";

  4.        koyomi="1월";

  5.        break;


  6.     case 2:

  7.        tsuki="2월";

  8.        koyomi="2월";

  9.        break;


  10.     case 3:

  11.        tsuki="3월";

  12.        koyomi="3월";

  13.        break;


  14.     case 4:

  15.        tsuki="4월";

  16.        koyomi="4월";

  17.        break;


  18.     case 5:

  19.        tsuki="5월";

  20.        koyomi="5월";

  21.        break;


  22.     case 6:

  23.        tsuki="6월";

  24.        koyomi="6월";

  25.        break;


  26.     case 7:

  27.        tsuki="7월";

  28.        koyomi="7월";

  29.        break;


  30.     case 8:

  31.        tsuki="8월";

  32.        koyomi="8월";

  33.        break;


  34.     case 9:

  35.        tsuki="9월";

  36.        koyomi="9월";

  37.        break;


  38.     case 10:

  39.        tsuki="10월";

  40.        koyomi="10월";

  41.        break;


  42.     case 11:

  43.        tsuki="11월";

  44.        koyomi="11월";

  45.        break;


  46.     case 12:

  47.        tsuki="12월";

  48.        koyomi="12월";

  49.        break;


  50.     default:

  51.        tsuki="";

  52.        koyomi="";

  53.        break;

  54. }

 

이것을 현대풍 멀티 스테이트먼트로 기술해 봅시다!

  1. switch(month){

  2. case 1: tsuki= "1월"; koyomi= "1월"; break;

  3. case 2: tsuki= "2월"; koyomi= "2월"; break;

  4. case 3: tsuki= "3월"; koyomi= "3월"; break;

  5. case 4: tsuki= "4월"; koyomi= "4월"; break;

  6. case 5: tsuki= "5월"; koyomi= "5월"; break;

  7. case 6: tsuki= "6월"; koyomi="6월"; break;

  8. case 7: tsuki= "7월"; koyomi= "7월"; break;

  9. case 8: tsuki= "8월"; koyomi= "8월"; break;

  10. case 9: tsuki= "9월"; koyomi= "9월"; break;

  11. case 10: tsuki= "10월"; koyomi="10월"; break;

  12. case 11: tsuki="11월"; koyomi= "11월"; break;

  13. case 12: tsuki="12월"; koyomi= "12월"; break;

  14. default: tsuki= ""; koyomi= ""; break;

  15. }

 

이렇게 되었습니다. 실로 컴팩트하고 시인성 좋게 되었습니다.

필자가 이것을 실천했을 때 「 어째서 멀티 스테이트먼트야!」라고 많은 물의를 일으킵니다. 이미 먼 과거의 것으로 여겨진 기술법을 꺼냈으니까 비판되는 것도 당연하다고 말하면 당연합니다. 그러나 한 번 이것에 익숙한 사람은 그만둘 수 없게 됩니다.


한번 더, 잘 봐 주세요.

 

각 case에 대응하는 처리가 세로에 깨끗이 줄서 한눈에 확인할 수 있습니다. 부주의 BUG 혼입을 막을 수 있기 때문에 유지보수 성이 올르고 또 소스도 컴팩트하게 되기 때문에 좋습니다.

 

만약 「아니! 그것은 이상하다!」라고 반론하고 싶어졌다고 하면 그것은 당신이 열중한 상식에 붙잡혀 있는 탓인지도 모릅니다.

 

"박살 내라 상식! 리얼 엔지니어의 길" 이만 마칩니다.

 

 예의 단순한 반복이 계속 되는 경우에 유효합니다. 복잡한 처리를 무리하게 멀티 스테이트먼트로 하는 것은 전혀 추천하지 않습니다.

Posted by 모과이IT
,

개발자가 놓지지 말아야 할 책 베스트10

Thinking In Java/Bruce Eckel
*Practical C Programming/Steve Oualline
Instant CORBA/Robert Orfali,Dan Harkey,Jeri Edwards
Modern Database Management/Fred R.McFadden,Jeffrey A.Hoffer,Mary B.Prescott
*Programming Pearls/Jon Bently
Effective C++/Scott Meyers
Unix Network Programming/W.Richard Stevens
*MicroC/OS-II The Real-Time Kernel/Jean J.Labrosse
Unix Internals:The New Frontiers/Uresh Vahalia
Extreme Programming Installed/Ron Jeffries,Ann Anderson,Chet Hendrickson

개발자가 놓지지 말아야 할 책 베스트40

Macintosh Human Interface Guidelines/Apple Computer Staff
Design Patterns/Gang of Four
*Refactoring/Martin Fowler
The Pragmatic Programmer:From Journeyman to Master/Andrew Hunt,David Thomas,Ward Cunningham(Preface)
*Peopleware:Productive Projects and Teams/Tom DeMarco & Timothy Lister
Linkers and Loaders/John R. Levine
Client Server Database Enterprise Computing/James Martin
DataWareHouse From Architecture To Implementation/Bary Devlin
Operation System Design-The XINU Approach/Douglas Comer
Writing Solid Code/Steve Maguire
Algorithm+Data Structure=Programs/NIclus Wirth
*Code Complete/Steve McConnell
Component Software:Beyond Object Oriented Programming/Clemens Szyperski
Software Reuse-Architecture,Process and Organization for Business Success/Ivar Jacobson,Martin Griss,Patrik Jonsson
Extreme Programming Explained/Kent Beck
Applying UML and Patterns,2nd Ed/Craig Larman
The Java Programming Languages, 3rd Ed/David Holmes,James Gosling,Ken Arnold
리눅스 완전분석으로 가는 길/박장수
*Operating System Concept/Abraham Silberschatz
TCP/IP Illustrated Volume I,II,III/W.Richard Stevens
*Advanced Programming in UNIX Environments/W.Richard Stevens
Understanding COM+/David S.Platt
Compilers: Principles,Techniques and Tools/Jeffrey D.Ullman
Numerical Reciples in C/William H.Press
The C++ Programming Language Special Ed/Bjarne Stroustrup
Effective STL/Scott Meyers
Professional Jini/Sing Li
C++ Primer/Stanley B.Lippman,Josee Lajoie
대용량 데이터베이스 시스템/이화식,조광원
Armchair Universe/A.K.Dewdney
Writing for Computer Science/Justin Zobel
*The C Programming Language/Brian W.Kernighan,Dennis M.Ritchie
Bugs in Writing Revisted:A Guide to Debugging Your Prose/Lyn Dupre
*The Design of The UNIX Operationg System/Maurice Bach
Building Business Objects/Peter eles,Oliver Sims
The Art of Computer Programming:Fundamental Algorithms/D.Knuth
Professional ATL COM Programming/Ricard Grimes
Pattern-Oriented Software Architecture, Volume 2/Douglas Schmidt
Inside Java2 Virtual Machine/Bill Venners
Understanding ActiveX/COM/David Chappell

개발자가 놓지지 말아야 할 책 베스트20

*Fundamentals of Data Structues in C++/Ellis Horowitz,Dinesh Mehta
*Computer Networks/Andrews.Tanenbaum
Modern C++ Design/Andrei Alexandrescu
Database System Concepts/Abraham Silberschatz,Henry F.Korth,S.Sudarshan
Modern Database Management/DaFred R.McFadden,Jeffrey A.Hoffer,Mary B.Prescott
Data Mining:Concepts and Techniques/Jiawei Han,Micheline Kamber
*The Design and Implementation of the 4.4BSD Operating System/Marshall Kirk               McKusick,Keith Bostic,Michael J.Karels
*UNIX Power Tools/Jerry D.Peek,Tim O’Reilly,Mike Loukides
The Unix Programming Environment/Brian W.Kernighan,Rob Pike(Contributor),Robert Pike
The Cathedral & The Bazaar/Eric S.Raymond
The Society of MIND/M.Mmsky
Fundamentals of Object Oriented Design in UML/Meilir Page-Jones
Computer Organization and Design:The Hardware/Software
Interface/David A. Patterson, John L. Hennessy
Design Web Usability The Practice of Simplicity/Jakob Nielsen
Introduction to Algorithms/Charles E.Leiserson,Ronald L.Rivest, Thomas H. Cormen
Introduction to the Team Software Process/Watts .Humphrey,Marc Lovelace
Mythical Man Month/Frederick P.Brooks
The Psychology of Computer Programming/Gerald M.Weinberg
After the Gold Rush/Steve C McConnell
Structure and Interpretation of Computer Programs - 2nd Ed/Harold Abelson,Gerald Jay Sussman,Julie Sussman


'생각하는개발 > 추천 개발도서' 카테고리의 다른 글

사고싶은책  (0) 2010.12.06
사랑하지 않으면 떠나라  (0) 2010.11.07
프로그래머의길, 멘토에게 묻다  (0) 2010.10.16
Code Complete 2  (0) 2010.10.16
Refactoring 한글판  (0) 2010.10.16
Posted by 모과이IT
,


 

“소프트웨어 개발이라는 긴 여로의 시작, 생각하는 프로그래머의 길은 어떻게 가야 하는가.” 

『실용주의 프로그래머』가 숙련된 프로그래머에서 마스터로 가는 깊은 통찰을 전해줬다면 이 책은 견습 프로그래머가 숙련 프로그래머로 성장하는 길을 안내하는 지침서다. 
흔히 프로그래밍을 공부하면서 진지한 고민 없이 인기 있는 언어를 선택하고, 개발에 몸담은 햇수를 기준으로 앞길을 결정하고는 한다. 
『프로그래머의 길, 멘토에게 묻다』는 당신이 소프트웨어 개발 분야에서 경력의 시작을 설계하고 이 분야에서 탁월한 개발자가 될 수 있도록 자기 자신을 세우는 일에 관한 책이다. 
프로그래밍을 생업으로 삼으며 견습이라고 부를 만한 시기에 어떻게 행동해야 이상적인 길을 걸을 수 있을지, 정말로 제대로 배우려면 어떤 마음가짐이어야 하는지, 커뮤니티를 어떻게 활용해야 내게 도움이 되는지 등 구체적인 상황과 해결책을 멘토의 조언을 빌어 제시한다.

 

<프로그래머의 길 멘토에게 묻다>

 

'생각하는개발 > 추천 개발도서' 카테고리의 다른 글

사랑하지 않으면 떠나라  (0) 2010.11.07
개발자가 놓치지 말아야 할 책 70권  (0) 2010.10.18
Code Complete 2  (0) 2010.10.16
Refactoring 한글판  (0) 2010.10.16
실용주의프로그래머  (0) 2010.10.16
Posted by 모과이IT
,


 

프로그래밍에 대한 최고의 실무적인 지침서로 널리 알려진 스티브 맥코넬의 CODE COMPLETE 제2판. 이번 책은 소프트웨어 개발 단계 중 "구현" 부분에 초점을 맞추고, 소프트웨어 구현에 대한 예술과 과학을 설명하기 위해서 최신의 기법들과 수백 개의 새로운 예제 코드가 포함되어 개정되었다. 

맥코넬은 연구와 학계, 그리고 상업적인 기법들에 있는 지식들을 바탕으로, 가장 효율적인 기법과 반드시 알아야 하는 원칙들을 이 실용적인 지침서에서 종합적으로 다루었다. 

스티브 맥코넬(Steve McConnell)은 개발 분야에 있어서 가장 뛰어난 저자이자 대변인 중 한 명으로 인정받고 있다. 그는 Construx Software의 수석 소프트웨어 엔지니어이며, Software Development 잡지의 Jolt Award를 수상한 Code Complete과 Rapid Development, 그리고 Software Project Survival Guide와 Professional Software Development의 저자이다.

 

<CODE COMPLETE 2>

Posted by 모과이IT
,

 

이 책은 기존에 존재하는 소프트웨어의 성능과 구조적인 무결성을 개선하기 위한 방법을 소개하는 책으로, 갈수록 복잡해지는 개발환경에 맞춰서 어떻게 해야 보다 효율적이고, 재사용이 가능한 소프트웨어를 개발할 수 있는지에 대해서 집중적으로 논의하고 있다. 여기서는 좋지 못한 코드로 재 작업하여 잘된 코드로 변환하는 적절한 방법을 소개하며, 그와 함께 "Refactoring"의 개념에 대해서 제대로 이해할 수 있는 기회를 제공한다. 

이러한 Refactoring을 통해서 실무자들은 소프트웨어의 결점을 보완할 수 있으며, 잘못된 코드로 인한 시간과 비용의 낭비라는 딜레마에서 헤어날 수 있을 것이다. Refactoring에 관한 한 이 책은 관련 기술 모두와 방대하고도 자세한 세부명세를 제공하고 있으며, 그것을 적용하기 위한 조언도 아끼지 않고 있다. 이러한 조언들은 단계적인 접근에 의해 보다 쉽게 익힐 수 있도록 하였다. 이 책에서 제공되는 모든 예제들은 Java라는 객체 지향언어로 작성 되었고, 객체 지향을 지원하는 어떠한 언어에서도 그 개념이 적용 가능하도록 작성하였다.

 

저자들

Martin Fowler는 컨설턴트로 10년 이상 객체를 주요한 기업 문제에 적용해왔다. 그는 의료, 금융, 회계 등의 분야에서 사용되는 시스템을 컨설팅했고, 그의 고객으로는 크라이슬러, 씨티뱅크, UK 내셔널 헬스 서비스, 앤더슨 컨설팅, 넷스케이프 커뮤니케이션 등이 있다. 또한 Fowler는 객체와 UML, 패턴에 관련된 정기 강연자이고, Analysis Pattern와 UML Distilled 등의 저자 이기도 하다.

Kent Beck은 저명한 프로그래머이자, 테스터, 리팩토링 전문가, 저자 그리고 밴조 연주자이다.

John Brant와 Don Roberts는 스몰토크에서 사용할 수 있는 리팩토링 브라우저(http://st-www.cs.uiuc.edut/~brant/RefactoringBrowser)를 개발했다. 이들은 또한 6년 동안 리팩토링의 실용적 측면과 이론적 측면을 연구한 컨설턴트이기도 하다.

William Opdyke는 객체지향 프레임워크에서의 리팩토링에 대한 연구로 이 분야의 중요한 업적을 남겼다. 그는 현재 Lucent Technologies/Bell Laboratories의 기술위원으로 있다.

 

<Refactoring (한글판)>

'생각하는개발 > 추천 개발도서' 카테고리의 다른 글

개발자가 놓치지 말아야 할 책 70권  (0) 2010.10.18
프로그래머의길, 멘토에게 묻다  (0) 2010.10.16
Code Complete 2  (0) 2010.10.16
실용주의프로그래머  (0) 2010.10.16
Gof의 디자인 패턴  (0) 2010.10.16
Posted by 모과이IT
,