임백준의 소프트웨어 산책

오랜만에 약간 휴식을 취할 겸 지하철 출퇴근에 읽었는데 생각보다 흥미로워서 정리를 해본다.


1. 객체지향

 - 퍼즐문제: 1~100의 사물함, 1번학생 부터 100번까지 문을 열기/닫기

    완전제곱수(1,4,9,...)의 특성을 파악해서 해결

 - 객체지향 언어에서 polymorphism, inheritance,encapsulation에 대한 본인의 입장과 

    철학은 무엇인가?        

 - 객체란 무엇인가?

 - 분산사건(discrete event) 시뮬레이션에 적합한 SIMULA 개발 (나이가드, 요한달)

    > SIMULA에서 클래스와 객체의 개념을 정립, 

       but 범용언어로 대중지지가 없어 Smalltalk가 최초라는 주장도 있음

    > 눈문 The Simula 67 Common Base Language

     "무수하게 많은 세세한 내용을 담고있는 시스템이나 문제를 다룰 때는, 분해(decomposition)가 제일 중요하다. 인간의 마음은 집중을 필요로 한다. 연관된 개념의 숫자를 충분히 작게 줄이는 것은 명확하고 조리있는 사유를 위해서 필수적이다. 커다란 문제를 분해하면 제한된 수의 세부사항을 담고 있기 때문에 한번에 다룰 수 있는 크기의 문제를 얻게 된다. 분석과 프로그래밍에 한 사람 이상이 참여하는 경우에는 적절한 분해가 받드시 요구된다.


  - Smalltalk (Alan Kay)

    세포(cell)라는 metaphor를 이용해서 프로그래밍을 쉽게 만드는 문제에 집중, 

    세포가 일종의 객체, 캡슐화의 개념

    나이가드와 달이 '복잡성의 극복'을 추구, 케이는 '단순성의 구현'을 추구함

    Object Oriented 라는 말을 처음 사용

    워드커닝험과 켄트백도 모두 smalltalk 프로그래머임

  - Parametric polymorphism : 컴파일타임에 파라메터로 지정된 형태, Java의 Generic

     Ad-hoc polymorphism  : 일반 overriding  

     다형성은 객체를 수정에 닫히고, 확장에는 열리도록 구성하는 'Open-close'원리에 

     입각해서 정의하는 가장 강력한 무기

  - 코드의 재사용과 상속   

     코드재사용의 방법을 찾기 위해 다익스트라(Dijkstra)나 베이커(Baker)는 

     구조적 프로그래밍의 방법론을 연구

      > 핵심은 모듈의 응집(module cohesion)과 모듈의 결합(module coupling)

         응집도는 높고, 결합도는 낮게...


2. 디자인패턴

  - 패턴은 반복적인 문제에 대한 공통의 해결방법(참조용)

  - 프로그래머간의 의사소통의 좋은 수단

  - 패턴의 본질을 파악, 카탈로그를 암기할 것이 아니라 해당 패턴을 사용하는 

    상황과 본질을 정확하게 이해 (해당 문제에 대한 이해 필요)

 - 크리스토퍼 알렉산더(Christopher Alexander)의 

    [A Pattern Language:Towns, Buildings, Construction ; 1977] 

    > 도시를 설계하는 방식, 방에 창문을 다는 방법 등 다양한 건축의문제를 다룬다

 - 워드커닝험(Ward Cunningham)과 켄트 벡(Kent Beck)가 1987년 OOPSLA

   (Object-Oriented Programming, Systems, Languages & Application)에 보고서를 제출

   "우리는 건축가이자 환경구조물센터의 창립자인 크리스토퍼 알렉산더의 연구를 적용해 정립한 개념을 이용해서 소프트웨어를 설계하고 구현하는 과정에 근본적인 변화를 꾀할 것을 제안한다. 알렉산더는 집과 사무실이 궁극적으로 그 안에서 살아갈 사람들에 의해서 설계되고 지어져야 한다고 주장했다. 그에 의하면 바로 그런 사람들이야 말로 특정한 구조물이 갖추어야 할 요구조건들을 가장 잘 이해하고 있기 때문이다. 우리는 이에 동의하며, 또한 동일한 원칙이 컴퓨터 프로그램에도 적용되어야 한다고 생각한다. 건물이든 프로그램이든 그들이 갖는 크기나 복잡성, 그리고 전문적인 설계를 위해서 필요한 오랜 훈련과정을 고려한다면 이와 같은 주장이 엉뚱하게 들릴지 모른다. 그렇지만 알렉산더는 매우 설득력있는 시나리오를 제시했다. 그것은 바로 '패턴언어'라고 불리는 개념이다"


 -  워드과 켄트가 '패턴언어'를 프로그래밍 세계에 끌어들이는 대한 최초의 불꽃을 당겼다면

    에릭감마(Erich Gamma)는 기름을 부어 큰불을 만들어낸사람

    (Junit과 Eclipse와 같은 오픈소스 개발자)


3. 리펙토링

  - 리펙토링은 소프트웨어 시스템의 원래 기능은 그대로 두면서 내부의 구조를 개선하는 것을 의미한다. 그것은 버그의 가능성을 최소화하기 위해서 코드를 깔끔하게 정리하는 엄정한 방법이다. 한마디로 리팩토링을 한다는 것은 이미 작성된 코드의 설계를 나중에 개선하는 것이다

 (마틴파울러의 Refactoring책 서문)


  - 폴 그레이엄: 인공지능언어인 LISP에 관한 교과서 저술할 정도의 깊은 내공

     Hackers & Painters 저자

     그레이엄이 고백한 프로그래밍 스타일은 마치 화가가 붓을 놀려서 그림을 완성해 나가는 것과 같은 점진적이고 반복적인 과정으로 이루어져 있다. 그는 프로그래밍을 시작할 때 전체적인 설계를 마치고 코딩을 시작하기 보다는 캔버스에 그림을 그릴 때처럼 조금씩 반복되는 작업을 통해서 코드에 살을 붙여 나갔다. 이과저에서 키보드는 붓이 되고 모니터는 캔버스가 되었다.

     (프로그래밍도 마치 스케치를 하는 방식과 다르지 않으며 예술적인 작업이다)


   - Refactoring의 전도사인 마틴 파울러(Marting Fowler)는 이런 방식에 대해서

      "리팩토링이 코딩에 앞선 설계(upfront design)를 대체할 수 있다는 주장도 존재한다.

       피팩토링을 염두에 둔다면 여러분은 설계를 할 필요가 전혀 없다. 머릿속에 가장 먼저 

       떠오르는 생각을 대충 코드로 구현한 다음, 그것이 제대로 동작하도록 수정하고, 

       리팩토링을 통해서 제대로 된 모양을 갖추도록 만들어 나간다. 이와 같은 방법은 아무 

       문제가 없다. 나는 이러한 방법을 통해서 대단히 잘 설계된 소프트웨어를 완성한 사람들을

      본적이 있다" 

      > 건축과 같이 리팩토링의 비용이 심한 경우는 해당되지 않지만, 사이버 세계에서는 가능함


  - 복잡성에 대한 두려움

     기본적인 초식과 멀티스레딩 등 심오한 분야도 정통한 영국의 개발자들이 개발한 

     컴포넌트는 지나치게 완벽한 시스템의 전형이었음

     객체간의 치밀한 연관관계, 요구조건을 뛰어넘는 보편적인 시스템을 만들려고 '과욕'을

     부린 지나치게 완벽한 시스템의 전형

     확장을 위한 일반화가 필요하지만, '과욕의 일반화'에 가까웠음

     > 잘못된 버그에 대해서, 컴포넌트의 커널에 해당 부분을 재설계해야 하는 상황이 됨

        '복잡성'에 대한 두려움 없는 용맹함 -> 본인들의 내공과 명석한 두뇌를 너무 신뢰

     > 단순성(Simplicity) : 프로그래머의 으뜸 덕목, 

        'Practice of Programming' (브라이언 커니건, 롭 파이크) 책에서 끊임없이 강조한 것

     > 단순함에 대한 미학

        좋은 프로그램의 특징: 단순성(Simplicity), 명확성(Clarity), 

          확장을 위한 일반성(Generality), 

          사람이 해야하는 수고를 덜어주는 자동화(Automation) 


  - 후각을 발달시키기

     Bad Smells

     . 중복된 코드 (Duplicated Code)

     . 긴 메소드 (Long Method)

     . 커다란 클래스(Large Class)

     . 긴 인수 (Long Parameter List)

     . 스위치 명령문 (Switch Statements)

     . 병령적인 상속구조 (Parallel Inheritance Hierarchies)

     . 추측에 근거한 일반화 (Speculative Generality)

     . 임시필드 (Temporary Field)

     . 설명문 (Comments)

   

 4. 소프트웨어 공학

   - 3명의 매니저를 만났음

     1) 꼼꼼한 여성 매니저: micro management 타입

          프로그래머의생산력을 극대화하는 장점, 자율적인 창의성은 억압하는 측면

     2) 자유방임스타일 흑인 매니저: 일정만 관리, 기술문제는 팀의 리더가 해결하도록 장려, 

          자신은 보고만 받음

          프로그래머의 창의력은 발휘할 수 있으나, 도덕적 헤이 발생

          소수의 프로그래머를 제외하면 스스로 동기부여를 하지 못하고 방황하기 쉬움

      3) 현재 소프트웨어를 설계한 매니저: 프로그래머로써의 모습이 남아있음, 

          자기 코드에 대한 애정(애착)이 강렬

         이런 애착을 배경으로 '프로그래머의 시각'에서 프로젝트를 관리하려고 노력

         시스템에 대한 강렬한 애착과 남다른 책임감, 프로그래머입장에서의 문제의식

         > 여성매니저의 꼼꼼함과 흑인 매니저의 자유방임이 갖는 장점이 결합

         > 선수 겸 코치에 가까워, 간혹 다른 선수들의 포지션을 정확히 결정해서 활용하지 못함

            실제 문제발생 시 적절한 프로그래머를 활용하기 보다 직접 키보드를 안고 해결하려 함

            당장은 그의 마음이 편해도 장기적으로 팀의 실력을 키우는 데 도움이 되지 않음 

    - 소프트웨어 프로젝트 관리

       컴퓨터 프로그래밍이 '컴퓨터를 위한 알고리즘'을 작성하는 것이라면, 

       소프트웨어 프로젝트관리는 프로그래머를 이용해서 '프로젝트를 위한 알고리즘'을 작성

       프로그래밍은 '논리의 예술', 프로젝트 관리는 '의사소통의 예술'


    - 애자일 소프트웨어 개발선언 http://agilemanifesto.org/principles.html

       > 경험이 풍부한 강사는, but 애자일이나 XP 원리의 일반적인 원칙은 동의하지만, 

         만능은 아님 


    - XP 프로그래밍

       "XP는 마치 퍼즐(jig saw puzzle)과 비슷하다. 많은 조각들이 존재하는 것이다.

       각각의 조각은 아무런 의미가 없다. 그렇지만 그들을 모두 결합하고나면 큰 그림이 보인다.

       이것은 XP가 전통적인 소프트웨어 개발 방법론과 결정적으로 다른 지점이다. 

       이렇게 함으로써 우리는 프로그래밍을 하면서 동시에 변경을 할 수 있는 길을 찾는다"

      > XP의 4가지 키워드: 의사소통, 단순성, 피드백, 용기 

      > Incremental and Iterative 개발모델과 차이점

         XP는 반복적인 회전 주기를 미리 상정하지 않음, 

        단 한번의 과정을 하더라도 수시로 의사소통과 피드백의 기회를 마련할 것을 권장함 

        일반적인 방법론과 주요차이점: Pair Programming, TDD

     

    - Pair Programming

      한사람은 코딩을하고 한사람은 생각, 바로 옆에 앉아서 같은 화면을 바라보는 형태

     "페어 프로그래밍은 소프트웨어 개발 일정에 영향을 주지 않음녀서 소프트웨어의 질을 향상

     시킨다. 이것은 직관적인 느낌에 반한다. 하지만 두 사람이 하나의 컴퓨터에서 일하는 것은 

     그것이 훨씬 더 높은 질의 소프트웨어를 생산하다는 사실을 제외하면 그들이 각자의 컴퓨터에

     서 일하는 경우와 (시간이라는 면에서) 다를 것이 없다. 이와 같은 품질의 향상은 프로젝트의

     후반부에 접어들수록 비용을 크게 절약해 준다"

     " 페어 프로그래밍을 하는 최선의 방법은 두 사람이 하나의 모니터 앞에 나란히 앉는 것이다.

       두 사람이 키보드와 마우스를 옆 사람에게 순서에 따라 넘겨준다. 한 사람이 코딩을 하면서

       현재 개발하고 있는 메소드에 대한 전술적인 사색을 한다. 한편 옆에서 앉아 있는 사람은

       그 메소드가 전체 클래스에서 어떤 위치를 점하는지 등을 전략적인 관점에서 고민한다.

       페어 프로그래밍에 익숙해지려면 시간이 좀 걸리므로, 처음에는 그것이 이상하게 느껴지

      더라도 걱정하지 않기 바란다"

     > 저자는 code review의 경험

         한 명이 개발한 내용은 반드시 검토자를 지정(해당 Task에 명시)하여 code review 실시

         문제 발생시 공동의 책임을 묻게 함

          즉, code review를 하는동안 해당 과정이 형식적이지 않은 매우 진지한 일부가 됨

          코드의 소유권을 희석시켜주며, 버그의 수정도 빠름


   - TDD

      "테스트를 실제 코드보다 먼저 작성해보면, 원하는 코드를 훨씬 더 빨리 작성할 수 있게된다

      는 사실을 깨닫게 될 것이다. 유닛 테스트와 그 유닛 테스트가 적용될 코드를 작성하는데 

      걸리는 시간은  유닛 테스트를 생략한 채 본래 코드만 작성하는 시간과 별로 차이가 없다. 

      만약 유닛 테스트가 이미 존재하는 경우에는 시간을 더 절약할 수도 있다"

      

    - 소프트웨어 공학

      프로그래밍을 절묘한 알고리즘을 고안해내는 창조적인 활동으로 국한시키는 것은 

      초보자가 저지르는 잘못임, 마치 축구를 '골'을 넣는 행위로 국한시키는 것과 같음

      축구란 골을 넣는 골잡이 외에 수비수, 미드필더, 골키퍼 등의 역할도 중요함

      무엇보다 실력과 카리스마를 갖춘 감독의 역할도 중요

      소프트웨어 공학의 핵심은 프로젝트의 성공을 위해서 사람들 사이에 의사소통이

      알맞게 형성되도록 만드는데 있다.


      정답은 없다. 어느 곳에서 'XP'가 최선이면 다른 곳에서는 '폭포수모델'이 최선일 수도 있다.

      어느곳에서는 그 둘을 합친 것이 효율적인 모델이 될 수도 있다.

      무수한 선택의 골짜기에서 바른 판단을 내리고, 의사소통이라는 강물을 트는 것이

      소프트웨어 공학이다.



5. XML

   - 경험담: 데이터 포맷을 XML로 변경할 때 데이터 처리속도에 대한 문의

    >  "별로 없다" 라는 답변: 

        하지만, 해당 데이터의 용량이 커질 수록 영향력이 커졌음

        "별로없다"와 "없다"는 같은 의미가 아니였음

        개발을 책임지는 사람이 다른 사람의 '조언'을 무비판적으로 수용하지 말아야 함

        유행어(Buzzword) 에 현혹되지 않는 냉철한 균형감각의 중요성을 깨달았음