소수설에서 태어난 다양한 주장들

지금까지 우리가 배운 것

  • 주류 oo
  • 이런저런 소수설
    • 다양한 소수설 같지만 사실 한두 손안에 꼽을 수 있는 사람들이 주장해온 것

소수설까지 알아야 하는 이유

  • 고집불통 소수설 신봉자들이 있기 때문
    • 일하다 보면 잘못된 곳에 소수설을 주장하며 일을 그르치는 사람들
  • 소수설이 틀리단 말이 아님
  • 말도 안되는 주장을 하는 사람에 대처하는 자세를 익히기 위해서

복습 OOP 토론시 피해야 할 사람

  1. 처음듣는 주장을 하며 그건 올바른 OOP가 아니야 라는 사람
  2. 이건 순수 OOP언어가 아니야 라는 사람
  3. 모든 프로그램은 OOP로 만들어야 해 라는 사람
  4. 어쩌고 한 누구가 이리 말했으니 너는 틀려 라는 사람
  5. 이 방법만 따르면 문제가 해결돼 라는 사람

ADT PDA

  • OOP 초창기에 OOP를 바라보던 두 가지 관점
  • Object Oriented Programming Versus Abstract Data Type
    • 이를 가장 잘 정리해둔 논문 (William R. Cook)
  • 현재 OOP는 둘다 섞여 있음
    • ADT(Abstract Data Types)
    • PDA(Procedural Data Abstraction)
    • 다수설의 입장과 마찬가지로 ADT가 좀 더 많이 들어있음

소수설은 기본적으로 PDA의 입장

  • 초창기 소수설 주창자 중 가장 영향력 있는 사람 : Alan Kay
  • 특히 OOP라는 용어를 처음 만든 사람으로 유명
  • Alan Kay의 OOP정의 OO의 핵심은 메시지
  • 본인의 주장을 Smalltalk란 언어로까지 만든 훈륭한 사람
  • 생물학 수학 전공

  • 극단적 주장을 하는 사람들도 주로 PDA에 기반을 두고 있음
  • 자기들의 주장에 대한 근거를 Alan Kay도 그랬다는 식으로 대곤 함
  • 확인해 보면 Alan Kay는 보통 그런적이 없음
  • 근거가 빈약한 사람들이 권위에 호소하려고 Alan Kay를 이용할 뿐
  • Alan Kay의 명예 회복을 위해 다음의 인터뷰를 소개
    • Dr. Alan Kay on the Meaning of Object Oriented Programming

Alan Kay가 개체를 바라보는 입장

  • 그에게 개체란 생물학에서의 세포 같은 존재
    • 즉 자기 결정권을 가진 어떤 생명체
  • 자신이 생물학을 전공했기에 그렇게 본다고 말함
  • 굳이 컴퓨터 환경에서 비슷한 것을 찾으면 네트워크에 존재하는 컴퓨터
    • 우리가 생각하는 단순한 개체보다는 어느 정도의 자기 결정권을 가진 존재
  • 개체로부터 데이터란 존재를 지워버리고 싶었음
  • 데이터가 없으니 개체 간의 상호작용은 메시지를 통해서만
    • 확실한 PDA 진영
  • 그가 개발한 스몰토크도 개체들로 구성된 살아 숨 쉬는 환경
    • 별도의 프로그램을 만들어 배포한단 개념이 없음
    • 모든 개체들이 존재하는 하나의 시뮬레이션 환경
    • 스몰토크 코드 편집기까지도 개체를 고치면 곧바로 변경됨

Alan Kay가 이용당하는 경우들

내 주장은 Alan kay의 주장에 기초하고 있기 때문에 옳은 방법이다.

  1. Alan Kay가 처음 OO를 창시한 사람이다
  2. ~는 정적 타입언어에 반대한다
  3. ~는 이른 바인딩에 반대한다

Alan Kay는 자기가 OO창시자라고 하지 않음

  • 이미 ADT를 기반으로 개체지향 비슷한 움직임은 진행되고 있었다고 함
  • 거기에 자기만의 주장을 했다고 함
  • 하지만 소프트웨어 공학자들은 이 의견을 받아들이지 않았음
  • 그 대신 ADT를 기반으로 오늘날의 개체지향을 완성시킴
  • 자기 주장에 기반을 둔 소수설이 아직까지 있는게 신기하다 생각

개체지향이란 용어를 처음 말한 건 맞다

  • 지금 하고 있는 게 뭡니까? 라는 물음에 답하면서 나온 용어
  • 그러나 지금 생각해보면 그 용어는 잘못된 거였다고 인정
  • 오히려 메시지 지향(message oriented)이라고 했어야 한다고 함
    • 개체를 구성하는 데이터는 중요하지 않고 메시지 전달만 중요하기 때문
    • Alan Kay의 메시지는 요즘 OO언어의 함수 시그내처와 좀 다름
    • 이런 생각을 프로그래밍 언어로 만든 것이 스몰토크
  • 즉 현재 개체 지향이라 불리는 것은 Alan Kay의 주장과 많이 다름

우리가 흔히 생각하는 메서드 호출

public class Calculator{
    public int add(int a, int b){
        return a + b;
    }
}
int val = add(1,2);

스몰토크의 메서드 호출

  • 스몰토크에는 이미 존재하는 메서드를 호출한단 개념이 없음
  • 컴파일 중에 올바를 메서드 시그내처를 호출하는지 검사도 불가
  • 그 보다는 다른 개체에게 이거해줘 라고 메시지만 보내는 시스템
    • 그 개체는 그걸 해주는 메서드를 가지고 있을 수도 아닐 수도 있음
    • 아니더라도 요청자는 여전히 메시지를 보낼 수 있음
public Object execute(String methodName, Object[] args){
    switch(methodName){
        case "addd":
            //args[0] + args[1] 반환
        case "mad"
            // args[0] * args[1] + args[2] 반환
    }
    //...
}
  • 인자 수 모자라면, 인자가 다르면, Name이 없는거라면 예외를 던질 수 밖에없음

스몰토크의 다형성

  • 어떤 메서드 시그내처를 미리 정의하고 따르는 개념이 아님
  • 따라서 다형성이 부모 클래스의 공통 시그내처에 의존하지 않음
  • methodName에 들어오는 문자열만 처리할 수 있다면 그게 다형성
  • 업계에서 일반적으로 말하는 다형성이 아님

스몰토크는 예외를 많이 던질수 밖에 없음

  • 주류 OO언어에서 컴파일러가 검사해주는 것도 스몰토크는 예외로
    • 매개변수 수가 틀려도
    • 메서드 이름이 잘못되어도
    • 매개변수 형이 틀려도 예외
  • 굉장히 많은 것을 예외에 의존하니 예외 처리가 중요해짐
    • 안그러면 제대로 도는 제품을 만들기 어려움
    • 예외 발생 시 회복해서 프로그램을 잘 돌게 만들어야 하는 일이 더욱 빈번

동적 타입을 선호할수록 예외로부터 안전한 프로그래밍을 중시(단, Alan Kay의 주장은 아님)

스몰토크의 모든 것은 늦은 바인딩

  • 모든게 동적 == 늦은 바인딩
  • 특히 Alan Kay는 모든것에 극도로 늦은 바인딩을 원했음
  • Alan Kay의 이런 자세를 다음과 같이 주장을 하는 사람이 악용
    • 정적타입보다 동적 타임이 옳습니다.

Alan Kay는 정적 타입에 반대했나?

  • 인터뷰에서 전혀 안 그렇다고 말함
  • 오히려 자기는 정적 타입 언어를 사용할때 힘들었다고 말함
  • 그래서 자기가 설계하는 언어는 동적 타입을 사용했다고
  • 즉 Alan kay는 컴퓨터 데이터를 보는 훈련을 거치지 않은 사람

Alan Kay는 겸손하고 훌륭한 과학자

  • 자기가 뭘 알고 뭘 모르는지 확실히 인지하고 있음
  • 자기의 주장이 소수설임을 확실히 인지하고 있음
  • 자기의 주장이 널리 안 받아들여져도 그에대해 분개하지 않음
  • 오히려 자기의 소수설을 실제 작동하는 언어로 완성시킴

고로 Alan Kay를 동적 타입이 옳다는 주장에 대한 권위자로 들 수 없음

동적타입은 실수를 유발한다.

  • 동적 타입 시스템에서는 컴파일러가 프로그래머 실수를 많이 못 잡아줌
  • 공짜 혜택을 제 발로 걷어차지 말자

다른 분야에서도 극단적 주장을 함

  • 프로젝트 관리
  • 품질보증 QA

극단적인 사람들의 예

  1. 모든것에 interface를 사용해야한다고 주장한 사람
  2. SOLID 설계정신을 정리한 사람
  3. 클래스 하나에 넣을 수 있는 최대 메서드 수는 4개라는 사람
  4. setter를 절대 사용하지 말아야 한다는 사람
  5. 오류 상황은 예외로만 처리해야 한다는 사람

익스트림 프로그래밍

  • eXtreme Programming (XP)
  • 애자일 소프트웨어 개발론 중의 일부
    • 코드를 어떻게 작성해야 하는가를 고민하는 게 아닌
  • 90년대부터 다양한 소프트웨어 개발 방법을 주장
    • 어떤 주장이든 간에 소프트웨어 품질을 높이는 게 목적이라고 말했었음
    • 많은 주장들은 아예 받아들여지지도 않았음
    • 일부는 실제로 흥했지만 대부분 짧게 흥했다 시들해지는 패턴 반복

pair programming

  • 짝 프로그래밍
  • 90대 말 2000년 대 초에 꽤 흥했던 유행어
    • 프로그래밍 관련 잡지에서도 여러 번 소개
    • 실제로 도입한 회사들도 제법 있었음

주장 둘은 하나보다 낫다

  • 두명이 같이 일하니 실수를 서로 잡아줘 버그가 줄어듦
  • 따라서 품질이 높아짐
  • 당연한 이야기

잠시 흥하고 사라진 이유

  • 실제 효과를 측정해보니 가성비가 안 맞음
  • 한 리서치에 따르면 페어 프로그래밍 후 문제가 약 15%줄음
  • 버그 15%감소가 인건비 2배보다 중요한 회사는 할 것임
    • 하지만 그렇지 않은 회사가 대부분
  • 이제 이런 헛소리 믿는 사람은 거의 없음
  • 하지만 코드 리뷰 프로세스는 남아서 업계에 도움을 줌

지속적 통합 (CI cContinuous Integration)

  • 원래는 Grady Booch(UML 창시자)가 주창한 방법
  • 이런 문제를 해결하려고 함

예시

  • A브랜치에서 A팀 진행중
  • B브랜치에서 B팀 진행중
  • A,B 브랜치 병합 : merge 충돌
  • A팀 팀장이 어떻게든 충돌 난 코드를 다 고침
  • 그러나 실수해서 버그 몇 개가 나옴 그것도 다 고침
  • A팀에서 기존의 어떤 로직에 기초해서 개발을 했는데 B팀이 그 로직 작동법을 바꿈
  • 두 팀이 같은 코드를 고친 건 아니지만 가정이 달라지면서 A팀의 일이 도루묵이 됨

지속적 통합 (CI cContinuous Integration)

  • 서로 각자의 브랜치에서 오랫동안 작업을 진행하지 말자
  • 종종 한 브랜치로 합쳐서 최대한 최신 코드에서 작업하게 하자
  • 실제 이 방법은 요즘 많이 쓰임
    • 가장 큰 이유 : 브랜치 관리가 쉬운 버전 관리 시스템이 등장
  • 정말 좋은 방법
  • 허나 이건 XP가 주장한 CI가 아님

XP의 CI는 극단적인 규칙을 만듦

  • 합치는 횟수는 반드시 하루에 여러 번이어야 한다
    • 그것도 모든 프로그래머의 작업물을 합쳐야 함
  • 이유 : 언제나 최신 버전에서 작업하니 시간 낭비를 막을 수 있다

하루에 브랜치를 몇 번씩 합치려면

  • 한 프로그래머가 하루에 완성하는기능이 여러 개라는 이야기
  • 매우 간단한 기능을 구현할 때나 가능
  • 설사 그렇더라도 테스트하는 시간도 필요
  • 원칙 : 개발자는 반드시 자기가 개발한 기능을 테스트한 뒤 커밋해야 함
  • 버그 있는 코드를 마스터에 합치면 다른 프로그래머가 일을 못하기 때문
  • 아주 간단한 기능만 만들어도 테스트하는 시간이 필요

XP의 CI가 특히 문제인 부분 : 테스팅

  • 어떤 기능을 가장 먼저 테스트하는 사람은 그 기능을 구현한 프로그래머
  • 하지만 구현자가 잡을 수 있는 버그에는 한계가 있음
  • 버그가 발생하는 가장 큰 이유 : 구현자가 요구사항을 잘못 이해해서
  • 이런 이유로 구현을 잘못한 사람은 그 문제를 스스로 알아채기 어려움

그래서 전문 테스터가 존재

  • 전문 테스터로 이 모든 걸 테스트하려면 인건비가 엄청나게 듦
  • 단순히 새로 구현된 기능만 테스트하는 것이 아님
  • 그로 인해 다른 것들이 망가질 수 있으니 전체적인 테스트를 해야함
  • 그러면 프로그래머 수 이상의 테스터가 필요하다는 이야기?

따라서 하루에 여러번은 좀 무리수

  • 프로그래머가 만드는 기능의 크기에 따라 하루 한 번도 어려울 수 있음
  • 어떤 경우에도 하루 여러 번 합쳐야 한다는 사람은 경험이 부족한 사람
  • 다행히도 업계가 이 꼬임에 빠지지는 않았음
    • Grady Booch 아저씨의 CI개념이 이미 훌륭했기 때문
    • 업계에서 CI라고 하면 XP의 CI가 아님

하지만 포기하지 않았다…

  • XP는 이 문제를 굳이 프로그래밍으로 해결하겠다며다른 방법론을 주장
    • TDD: 테스트 주도 개발(Test Driven Development)
    • 이 방법론은 최근에 흥했다가 다시 수그러들고 있는 중
    • 아직도 근본적인 문제를 직시 못하는 해결법

테스트 주도 개발

  • 개발 과정을 테스트 우선으로 바꿈
  • 기능을 구현하기 전에 반 드 시 테스트하는 코드부터 만들어야 함
  • 기능부터 만들던 기존의 방법과 반대
  • 테스트코드를 작성하는 사람 == 기능을 구현하는 사람
    • 매우 큰 문제

TDD 하에서 프로그래머의 개발 과정

  • 어떤 기능을 만들어야 하는지 숙지함
    • 제품 책임자(product owner)등이 제공한 사용자 스토리나 명세 등을 통해
    • 당연히 회의 등을 소집해서 토론할 수 있음
  • 그 기능이 제대로 동작하는지 테스트할 코드를 만듦
    • 아직 기능은 구현하지 않았음
    • 주로 단위테스트(unit test, 메서드를 하니씩 테스트)를 이용
    • 보통 메서드 호출 뒤 그 결과가 예측한 결과와 일치하는지 비교
    • POCU의 과제, 실습에서 제공하는 테스트 코드와 비슷
  • 기능을 구현
  • 2에서 만든 테스트를 실행
    • 실패하면 잘못 구현한 것 : 3으로 돌아감
    • 통과하면 제대로 구현한 것
  • 이미 소스코드 저장소에 있는 다른 단위 테스트들을 모두 실행
    • 실패하면 내가 남의 코드를 고장 낸 것 : 3번으로 돌아감
    • 통과하면 아무 문제 없는 것
  • 구현 코드와 테스트 코드를 모두 소스코드 저장소에 추가

XP진영의 주장

  • TDD를 사용하면 극단적인 CI를 해도 문제 없음
  • 하루 여러 번씩 브랜치를 합쳐도 코드를 통해 자동으로 테스트
  • 단 구현되어 있는 모든 함수에 대해 단위 테스트를 만들어야 함
    • 코드 커버리지 100%
  • 언제나 모든 코드를 테스트하니 품질이 높아짐

TDD를 하면 정말 품질이 높아지지만…

  • 당연히 모든 코드에 단위 테스트를 실행하면 품질이 높아짐
    • 다른 조건이 다 동일할 경우의 이야기
  • 그러나 다시 근본적인 문제에 대해 생각해야 함
    • 품질이 얼마나 높아지는가?
    • 그러려면 드는 비용(ex: 테스트 코드 작성하느라 생산성 저하)은 얼마인가?
  • 업계가 페어 프로그래밍을 포기했다는 사실을 잊지 말자
  • 과연 제대로 된 테크트 코드를 작성할 수 있는가 라는 문제도 있음

TDD는 설계능력을 향상시켜 준다는 주장

  • TDD는 함수 별로 단위 테스트를 돌려야 함
  • 따라서 프로그래머는 기능 하나하나를 작은 함수로 분리해야 함
    • 모듈화, 유연성 향상

경제논리와 안전

  • 버그가 없는 프로그램을 만들고 싶어 하는 장인정신은 존경
  • 하지만 실상은 경제논리에 따라 좌우된다
    • 종종 제품 개발비를 아끼려 최종 사용자에게 테스트를 미룸
    • 이상적인 세계에서는 모든 버그를 다 잡고 출시하는 게 맞음
    • 하지만 약간 불안정한 제품을 사용하면서 할인을 받으려는 사용자도 충분
  • 단 인간의 생명을 위태롭게 할 수 있는 버그라면 경제논리는 후순위

현존하는 테스트 중 단위 테스트는 가장 비효과적인 테스트 중에 하나임

효과적인 테스트 : 최종 테스트 vs 부품 테스트

  • 최종 제품 테스트와 부품 테스트 중 하나만 해야 한다면
    • 최종 제품이 제대로 작동하는 게 제일 중요하기에 최종 제품 테스트
    • 부품에 문제가 없어도 최종 제품에 문제가 있을 수 있음
    • 최종 제품 테스트도 UI 자동화를 통해 자동 테스트 가능
  • 물론 제품 규모가 커지면 최종 제품만 테스트만 할 수는 없다
    • 적당한 크기로 분리한 각 부분의 동작을 테스트하는 게 더 효과적
  • 하지만 과연 적절한 크기가 함수 하나일까?

효과적인 테스트 : 테스트의 주체

  • 같은 사람이 구현과 테스트를 모두 하는 건 효과적이지 못함
    • 이미 실수르르 하고 있는 사람이 자신의 실수를 알아채기는 힘듦
  • 자동차 업계에서도 제조자와 안전성 테스트 하는 사람이 다름
    • 즉 테스트 전문가가 있음
    • 테스트 프로세스도 보통 인증 받은 정형화된 프로세스

테스트는 전문가에게 맡겨라

  • 소프트웨어 개발 업계에서도 테스트 전문가(QA)가 있음
    • 제품을 오작동하게 만드는 상황을 찾는 데 특화된 인력
    • 프로그래머가 방패라면 QA는 창
  • 안전을 중요시하는 곳에서는 표준화된 QA프로세스를 따라 테스트 함

POCU 학생들의 습관을 봐도 이게 보임

  • 내가 작성한 테스트 코드를 다 통과해도 점수는 100점이 안 됨
    • 빌드봇이 틀렸다고 잡아줌
    • 남이 만든 테스트 코드에서 잡힘
  • 위에서 내가 작성한 테스트 코드가 바로 TDD
  • 그러면 내 테스트 코드를 더 꼼꼼히 작성 안 하는 이유는?
    • 가성비
    • 남의 테스트가 더 효율적/효과적이란 사실을 이미 잘 알고 있음

코드 커버리지 100%를 위해

  • 아주 간단한 더하기 함수 같은 건 단위 테스트를 작성하기 쉬움
  • 그보다 훨씬 복잡한 예는? (예: DB속 데이터가 필요한 기능)
    • DB 접속이 안 되어 있으면 테스트 불가능
    • 테스트 실패 시 DB 문제이지 내 코드 문제인지 모름
  • 따라서 TDD에서는 이런 경우 DB에 직접 연결하지 말라 한다
  • 그 대신 DB의 동작을 그대로 흉내내는 mock개체를 만들라고 함
    • 이 개체는 실제 데이터가 아니라 테스트 데이터를 반환

단위 테스트와 mock 개체의 비용

  • 단위 테스트를 하는 메서드 범위 밖의 많은 테스트용 개체를 만들어야 함
    • 그 후 실체를 바꿀 때마다 테스트 개체도 바꿔야 함
  • 그와 반대로 1주에 한 번 정도씩 코드를 다 합쳐 전체 테스트를 하면?
    • 전문 QA들이 테스트
    • 혹은 UI 자동화 프로그램을 이용한 자동 테스트
  • 테스트용 개체 제작에 시간을 낭비할 필요가 없음

단위테스트의 용도

안전이 매우 중요하다면 고려할만하다

  • 단 이미 최종 테스트도 하고 전문 테스터도 있는 경우
  • 안전이 매우 중요하다면 가성비가 안 좋은 TDD까지 추가할 수 있음
  • 타 업계도 안전이 중요하면 부품까지 꼼꼼히 테스트하는 것과 마찬가지

전문 테스트 인력이 없어도 고려해볼 만하다

  • 테스터 대신 프로그래머에게 TDD를 시키는 건 이상한 이야기
    • 일반적으로 테스터의 연봉보다 프로그래머 연봉이 높음
  • 하지만 아예 테스터가 없는 경우도 있음
    • 예 개인이 진행하는 오픈소스 프로젝트
    • 전문 QA를 하나라도 둘 만큼 프로그래머의 아웃풋이 많지 않음
  • 이럴 때는 테스트를 아예 안 하는 것보다 단위 테스트라도 있는 게 나음
  • 하지만 여전히 UI자동화를 통한 최종 제품 테스트가 더 효과적

단위테스트가 무조건 나쁘다는 게 아니다

  • POCU 아카데미 내부 기술에서도 사용하는 곳이 있음
  • 특히 비지니스 로직과 먼 알고리듬 관련 기능일 때 쉽게 사용 가능
    • 매개변수만으로 어떤 함수에 필요한 데이터를 모두 전달 가능
    • 이미 정형화된 알고리듬이라 바뀔 일이 적음
    • 원래 제대로 작동하던 데이터가 기능 수정 후에도 멀쩡한지 확인하는 용도

다른 테스트 방법이 더 효과적인 기능들

  • 자주 변하는 기능
  • 다른 서브 시스템에 의존하는 기능
  • 기술적이기보다 비즈니스 로직을 구현한 기능

단위 테스트를 위한 다형성

모든걸 인터페이스로 만들어야 한다

  • 왜냐면 이제 구현이 두 개
    • 실제 개체 클래스 하나, mock 개체 클래스 하나
  • 따라서 모든 메서드를 인터페이스로 표현해야 함
    • 테스트할 땐 mock 클래스
    • 실제 프로그램 실행할 때는 실체 클래스
  • 즉 단위테스트를 위한 다형성을 주장

역사는 흘러 심판의 시간 : Python

  • Python은 Guido van Rossum가 만든 대표적인 동적 타입 언어
  • 이 분이 은퇴 전에 일했던 마지막 회사 DropBox
  • 마지막까지 정적 타입이 없어 생기는 문제를 해결하려고 엄청 노력
    • 프로그래머 수가 무지 많음
    • 코드그ㅏ 400만 줄이나 됨
    • 따라서 동적 타입 때문에 라이브 환경에서 생기는 문제들이 너무 심각했음
  • 동적 타입 언어 때문에 라이브에서 문제 생긴 다른 제품도 많음
    • 궁금하면 검색해볼 것

역사는 흘러 심판의 시간2 : JavaScrpt

  • 대표적인 동적 타입 언어
  • 웹 프론트엔드에서 주로 사용해옴
  • 최근에 프론트엔드 기술 발전과 더불어 동적 타입이 문제 됨
  • 그걸 고치려고 나온 프로그래밍 언어 중 가장 대표적인 게 TypeScrpt
    • 처음엔 동적 타입이 최고라며 이건 실패할 거라 하는 사람이 많았음
    • 몇 년 지나보니 주류 프론트엔드 프레임워크가 TypeScrpt를 기본으로 지원