본문으로 건너뛰기

"programming" 태그로 연결된 4개 게시물개의 게시물이 있습니다.

모든 태그 보기

· 약 50분
karais89

프로그래밍의 정석 요약

책에서의 용어 설명

  • 모듈
    - 함수나 변수를 어떤 책임 단위로 묶어낸 것은 모듈로 통일한다.
    연관성이 높은 코드를 한데 묶었다는 의미에서 클래스, (함수나 변수를 모은 하나의) 파일, 컴포넌트, 부품, 라이브러리라는 용어도 있는데, 이 용어들을 모두 포함해서 모듈이라고 부른다.
  • 함수
    - 코드 일부를 떼어내어 호출할 수 있게 만든 것은 함수로 통일한다.
    루틴, 함수, 프로시저, 메시지, 메서드, 멤버 함수 등 용어는 세부적으로 나뉘는데, 이 용어들은 모두 포함해서 함수라고 한다.

책에서의 참고 서적

원리 원칙 리스트

  • 프로그래밍에 은제 탄환은 없다
    • 프로그래밍에 마법 같은 해결책은 없다.
  • 코드는 설계서다
  • 코드는 반드시 변경된다
    • 코드가 변경된다는 사실은 코드를 작성할 때 다양한 판단, 선택, 결단을 하는 데 있어서 최우선으로 고려해야 한다.
  • KISS (Keep It Simple, Stupid / Keep It Short and Simple)
    • 간단하게 해라, 어리석은 녀석아 / 간결하고 단순하게 해라
    • 코드를 작성할 때는 최우선 가치를 단순성과 간결성에 둔다.
  • DRY (Don't Repeat Yourself 중복하지 마라)
    • 똑같은 코드를 중복해서 작성해서는 안된다
  • YAGNI (You Aren't Going to Need it 그것은 분명 필요 없어진다)
    • 정말로 필요해졌을 때 필요한 코드만을 작성한다는 방침으로 프로그래밍에 임해야 한다
  • PIE (Program Intently and Expressively 의도를 표현해서 프로그래밍하라)
    • 코드를 작성할 때는 의도를 명확하게 표현해야 한다는 점이 중요하다
    • 코드는 컴파일러가 아닌 사람이 읽기 위한 것이기 때문이다
    • 코드를 작성할 때는 작성하기 쉬움 보다는 읽기 쉬움을 중시하자.
  • SLAP (Single Level of Abstraction Principle 추상화 수준의 통일)
    • 추상화 단계를 분리할 때는 기능의 복잡도에 따라 여러 계층으로 분리한다.
  • OCP (Open-Closed Principle 개방-폐쇄의 원칙)
    • 코드는 확장에 대해서 열려 있고 수정에 대해서 닫혀 있는 2가지 속성을 동시에 충족하도록 설계한다
    • 확장에 대해서 열려 있다는 말은 코드의 동작을 확장할 수 있다는 의미이다.
    • 수정에 대해서 닫혀 있다는 말은 코드의 동작을 확장하더라도 그 밖의 코드는 전혀 영향을 받지 않는다는 의미이다.
    • 코드에 인터페이스를 사용한다
    • OCP의 대표적인 패턴 (스트레티지, 옵저버, 탬플릿 메서드,데코레이터)
  • 명명이 중요하다
    • 이름을 붙이는 행위와 그런 과정을 통해 생겨난 이름 자체에 모두 중요한 가치가 있다.
    • 다음 사항에 주의한다.
      • 이름에는 더 많은 정보를 담도록 한다. 이름을 짧은 주석이라고 생각한다.
      • 이름을 오해받지 않도록 주의한다. 다른 의미와 혼동되지 않도록 몇 번이고 자문자답해야 한다.
      • 이름이 효과와 목적을 설명하도록 한다.
      • 이름은 발음 가능한 것으로 한다
      • 이름은 검색 가능하도록 붙인다.
  • 프로그래밍 이론
    • 최고의 코드란 확장 방법이 다양하게 존재하고 불필요한 요소가 존재하지 않으며 읽기 쉽고 이해하기 쉬운 코드다.
      • 의사소통
        • 코드는 남에게 보여주는 문서다. 그리고 문서의 본질은 의사소통 수단이다.
        • 프로그래밍에서 의사소통이 원할하다는 것은 코드를 읽은 사람이 코드를 이해할 수 있고, 코드를 수정할 수 있으며, 코드를 사용할 수 있다는 뜻이다.
      • 단순함
        • 코드가 단순하다는 것은 코드에서 불필요한 복잡성이 제거된 상태를 가리킨다.
      • 유연성
        • 코드에서 유연성이란 코드 변경이 용이함을 뜻한다.
  • 결과의 국소화
    • 변경이 미치는 영향이 국소에 머무르도록 코드를 구성한다.
  • 반복의 최소화
    • 반복이란 중복을 뜻한다. 즉 중복을 최대한 제거한다는 뜻이다.
  • 로직과 데이터의 일체화
    • 로직과 해당 로직이 조작하는 데이터를 서로 가까이에 배치시키는 것을 뜻한다.
    • 여기서 가까이란 같은 함수 혹은 같은 모듈이며 가까우면 가까울수록 좋은 코드다.
  • 대칭성
    • 대칭성이란 일반적으로 어떤 변환에도 변하지 않는 성질을 가리킨다.
  • 선언형의 표현
    • 선언형의 표현이란 코드의 의도를 전하고자 할 때 가능한 한 명령형보다는 선언형으로 표현하는 것을 뜻한다.
    • 명령형 프로그램은 문제의 해법, 즉 자료구조와 알고리즘을 기술한다.
    • 반면에 선언형 프로그래밍은 문제의 정의, 즉 해결해야 할 문제의 성질이나 이때 충족해야 할 제약을 기술한다.
  • 변경빈도
    • 변경 빈도란 코드를 수정하는 시점이 같다는 의미이다. 즉 변경 이유가 같다는 뜻이다.
    • 같은 시점에 변경되는 요소는 같은 곳에 두고, 다른 시점에 변경되는 요소는 다른 곳에 분리해 두도록 한다.
  • 아키텍처 기본 기법
    • 소프트웨어 아키텍처를 적절하게 구축하는 데 필요한 기초 원리
    • 추상
      • 추상이란 개념적으로 명확한 선 긋기를 수행하는 것이다.
      • 추상은 사상과 일반화라는 2가지 관점에서 정리된다.
        • 사상 : 복잡한 대상의 몇 가지 성질을 버리고 특정한 성질에 주목하는 것
        • 일반화 : 구체적인 대상으로부터 공통 성질을 추출해서 더욱 범용적인 개념으로 정싱화하는 것
    • 캡슐화
      • 관계성이 강한 데이터와 로직을 모듈이라는 껍질로 감싸는 것을 캡슐화라고 부른다.
    • 정보 은닉
      • 모듈의 구현을 해당 모듈을 사용하는 클라이언트로부터 은닉한다.
    • 패키지화
      • 모듈을 의미 있는 단위로 모은 다음 그룹화한다.
    • 관심의 분리
      • 관심이란 소프트웨어의 기능이나 목적을 뜻한다.
      • 관심을 분리한다는 것은 각각의 관심에 관련된 코드를 모아 독립된 모듈로 만들어 다른 코드로부터 분리한다는 뜻이다.
      • 대표적인 패턴 MVC
    • 충족성, 완전성, 프리미티브성(원시성, 순서성)
      • 모듈이 담당하는 추상에 대한 표현은 충분하고 완전하며 프리미티브여야 한다.
      • 충족성
        • 모듈이 표현하고자 하는 추상이 그것을 전하기에 충분한지를 뜻한다.
        • 모듈이 컬렉션을 표현하고 있을 때 remove가 제공된다고 해도 add가 제공되지 않는다면 컬렉션이라는 점을 전하기에는 불충분하다.
      • 완전성
        • 모듈이 표현하고자 하는 추상이 모든 특징을 갖추고 있는지를 뜻한다.
        • 모듈이 컬렉션을 표현하고 있을 때 요소의 개수를 구하는 size가 제공되지 않는다면 완전하다고 할 수 없다.
      • 프리미티브성
        • 모듈이 표현하고자 하는 추상이 모두 순수한지 아닌지를 의미한다.
        • 모듈이 컬렉션을 표현하고 있을 때 아이템을 1개 추가하는 add가 제공된다면 아이템을 10개 추가하는 add10은 필요하지 않다.
    • 정책과 구현의 분리
      • 모듈은 정책 혹은 구현을 다룬다. 다만 하나의 모듈에서 양쪽 모두를 다루어서는 안 된다.
    • 인터페이스와 구현의 분리
      • 모듈은 인터페이스 파트와 구현 파트 2개의 분리된 부분으로 구성한다.
        • 인터페이스 파트 : 모듈이 가진 기능을 정의하고 모듈의 사용 방법을 정하는 부분 클라이언트에서 접근할 수 있는 함수의 원형으로 구성된다.
        • 구현 파트 : 구현 파트란 모듈이 가진 기능을 실현하는 코드 부분. 모듈이 내부에서 사용하는 로직과 데이터가 포함된다. 구현 파트는 클라이언트에서 접근할 수 없다.
      • 사용자는 인터페이스만 알면 된다.
    • 참조의 단일성
      • 모듈의 요소에 관한 선언과 정의는 1회로 제한한다
      • 정의가 1회라는 말은 예를 들어 변수값을 초기화했다면 이후 값은 변경하지 않는다는 뜻이다.
      • 이렇게 하면 변수값의 변화를 추적하지 않아도 되므로 직관적인 코드가 된다.
    • 분할 정복
      • 그대로는 해결하기 어려운 커다란 문제는 여러 개의 작은 문제로 분할해서 개별적으로 해결한다
  • 아키텍처 비기능 요구사항
    • 정의: 기능 외적인 면 전반에 관한 요구사항
    • 변경 용이성
      • 변경 용이성이란 해당 소프트웨어를 얼마나 쉽게 개선할 수 있는지에 대한 능력
      • 해당 소프트웨어를 쉽게 수정할 수 있는지, 쉽게 확장할 수 있는지, 쉽게 재조직할 수 있는지, 쉽게 다른 플랫폼으로 이식할 수 있는지 등의 능력
    • 상호 운용성
      • 상호 운용성이란 소프트웨어가 다른 소프트웨어와 정보를 주고받을 수 있는 능력
    • 효율성
      • 효율성이란 소프트웨어가 실행되면서 동반되는 리소스 사용에 있어서 적절한 성능을 끌어내는 능력
      • 시간 효율성
      • 자원 효율성
    • 신뢰성
      • 신뢰성이란 소프트웨어가 예외적인 상황 혹은 예기치 못한 방법이나 부정한 방법으로 사용된 상황에서도 기능을 유지하는 능력
    • 테스트 용이성
      • 테스트 용이성이란 소프트웨어에 대해 효과적이면서 효율적으로 테스트를 수행하는 능력
    • 재사용성
      • 재사용성이란 소프트웨어를 전체가 됐든 일부가 됐든 다른 소프트웨어 개발에 재사용하는 능력을 뜻한다.
  • 7가지 설계 원리
    • 7가지 설계 원리란 결함을 만들어 내지 않기 위해 고려해야 할, 코드 구조상의 7가지 핵심 관점을 뜻한다.
    • 단순 원리
      • 단순 원리란 단순함을 중시한다는 원리다.
      • 극단적으로 말하자면 프로그래밍 생초보도 읽을 수 있을 만큼 일관되고 단순한 코드를 작성해야 한다.
    • 동형 원리
      • 동형 원리란 형태를 중시한다는 원리다.
      • 어떤 모듈에서 다루는 숫자의 단위, 공개 함수의 파라미터 수, 사용 순서 등이 통일된다는 것을 의미한다.
      • 일관성 있는 코드를 작성하자.
    • 대칭 원리
      • 대칭 원리란 형태의 대칭성을 중시한다는 원리다.
      • 어떤 플래그가 참일 때의 처리가 있다면 거짓일 때의 처리도 있어야 한다.
      • 명명의 대칭성에도 신경 쓰자. set/get, start/stop, begin/end, push/pop 등
    • 계층 원리
      • 계층 원리란 구조의 계층성을 중시한다는 원리다.
      • 리소스를 할당했다면 같은 계층에서 리소스를 해제해야 한다.
      • 배타 제어를 위해 플래그를 걸었다면 같은 계층에서 플래그를 해제해야 한다.
    • 선형 원리
      • 선형 원리란 처리의 직선적 흐름을 중시한다는 원리다.
      • 오류는 복잡한 조건문이나 반복문에서 많이 발생한다.
      • 위에서 아래를 향해 한 방향으로 내려가는 코드 흐름은 단순명쾌하고 이해하기 쉽다.
      • 분기가 적은 코드를 작성한다.
    • 명증 원리
      • 명증 원리란 로직의 명증성을 중시한다는 원리다.
      • 명증성이란 확실하게 증명한다는 의미다.
    • 안전 원리
      • 안전 원리란 안전성을 중시한다는 원리다.
      • 필연성이 없는 곳이나 모호한 곳은 안전한 쪽으로 설계하고 프로그래밍해 두는 것이다.
  • UNIX 사상
    • UNIX 사상이란 뛰어난 프로그래밍을 수행할 수 있는, 경험에 기반을 두고 있는 실천적인 노하우의 집합이다.
    • 모듈화의 원칙
      • 명료한 인터페이스로 결합한 단순한 모듈들로 소프트웨어를 조립해야 한다
      • 코드 중에 관계성이 높은 요소를 모아 모듈을 작성한다
      • 모듈이 제공하는 인터페이스는 불필요한 것은 제외하고 가장 적게 만들자
      • 모듈의 구성 요소는 관계성이 높은 것만 모아 놓도록 한다.
    • 명확성의 원칙
      • 코드는 교모하게가 아니라 명확하게 작성해야 한다
    • 구성의 원칙
      • 소프트웨어는 다른 소프트웨어와 조합할 수 있도록 만든다
    • 분리의 원칙
      • 메커니즘에서 정책을 분리한다.
      • 정책
        • 해당 소프트웨어의 전제에 종속되는 부분
        • 비즈니스 로직이나 사용자 인터페이스
      • 메커니즘
        • 해당 소프트웨어의 전제에 종속되지 않는 독립된 부분
        • 그래픽 처리의 래스터 변환 등 엔진 역할을 수행하는 부분
    • 단순성의 원칙
      • 코드가 단순해지도록 설계한다
    • 절약의 원칙
      • 큰 코드는 작성하지 않도록 한다
      • 코드의 분량이 큰 것과 코드 내부의 복잡도가 큰 양쪽을 의미한다.
    • 투명성의 원칙
      • 소프트웨어의 동작을 바깥에서 이해하기 쉽게 보이도록 설계한다
    • 안전성의 원칙
      • 일반적인 조건뿐만 아니라 예상외의 조건에서도 적절하게 동작되는 것
    • 표현성의 원칙
      • 코드에서 정보를 표현할 때는 로직이 아닌 데이터에 모아 작성하는 방식으로 한다
    • 충격 최소의 원칙
      • 인터페이스는 사용하는 사람이 상상하는 형태대로 동작하도록 설계한다
    • 침묵의 원칙
      • 소프트웨어는 표시를 최소한으로 줄이고 과묵하게 작업을 수행해야 한다
    • 복구의 원칙
      • 소프트웨어 동작 중 오류 복구에 실패했다면 처리를 계속해서는 안 된다
      • 나아가 해당 오류는 가능하면 한눈에 띄도록 발생시킨다
    • 경제성의 원칙
      • 프로그래머의 시간을 절햑해야 한다
      • 시간 낭비가 되는 리스트
      • 빈약한 하드웨어
      • 사용 소프트웨어에 대한 제한
      • 환경에 관한 규제와 제한
    • 생성의 원칙
      • 코드를 작성하기 위한 코드를 작성한다
      • 코드 생성기를 만든다
    • 최적화의 원칙
      • 빠른 코드보다 바른 코드
    • 다양성의 원칙
      • 소프트웨어에서는 선택의 다양성을 수용한다
      • 소프트웨어에 관한 모든 상황에서 유일하게 바른 방법은 존재하지 않는다
      • 더 좋은 방법을 계속 찾는다
    • 확장성의 원칙
      • 확장성을 고려한 설계를 수행한다
  • UNIX 철학
    • UNIX적인 사고방식
    • 작은 것이 아름답다
      • 작게 만들고 작게 유지하도록 한다
      • 장점
        • 이해가 쉽다
        • 보수가 쉽다
        • 머신 자원에 부담을 주지 않는다
        • 다른 소프트웨어와 조합하기 쉽다
    • 한 번에 하나의 작업
      • 하나의 소프트웨어에는 하나의 작업만 제대로 시킨다
      • 가장 좋은 소프트웨어란 생애 중에 단 하나의 작업만을 제대로 완수하는 소프트웨어다
    • 즉시 프로토타입 진행
      • 가능한 한 빨리 프로토타입을 작성한다
      • 어떤 아이디어가 성공할 것 같은지, 눈에 보이는 형태로 현실화 할 수 있는지를 확인하려면 시험 삼아 만들어보는 방법이 가장 좋다
    • 효율성보다 이식성
      • 소프트웨어 설계는 선택의 연속이다
      • 이식성과 개발 효율성이라는 이율배반적인 선택을 해야되는데 이때는 이식성을 우선시해야 한다
    • 데이터는 텍스트로
      • 데이터는 텍스트 파일로 저장한다
      • 데이터의 이식성도 중시해야 한다
      • 거의 모든 면에서 바이너리 파일보다 뛰어나다
    • 레버리지 소프트웨어
      • 레버리지(지렛대)
      • 코드를 대량으로 작성하는 가장 좋은 방법은 빌려 오는 것이다
      • 각각이 단일 기능이며 단일 가치에 집중하는 작은 소프트웨어를 작성하자
    • 셸 스크립트 활용
      • 셸 스크립트를 통해 지렛대 효과와 이식성을 높인다
      • 셸 스크립트는 이식성이 높다
    • 대화형 인터페이스 회피
      • 대화형 인터페이스 회피
      • 지나친 대화형 인터페이스를 피하도록 한다
      • 대화형 인터페이스의 문제
        • 소프트웨어별로 독자적인 대화 방법을 기억해야 한다
        • 소프트웨어끼리 대화할 수 없다
        • 대기 시간이 많아진다
        • 입력 부분에 대한 해석 코드가 많아지고 흉해진다
        • 큰 것이 아름다운 접근법으로 변질된다
    • 필터화
      • 모든 소프트웨어를 필터로 설계한다
      • 필터란 입력 스트립을 데이터로 받아들여 어떤 형태로든 가공한 다음 가공된 데이터를 출력 스트림으로 송출하는 것이다
      • 소프트웨어의 본질은 데이터를 처리하는 것이지 생성하는 것이 아니다
  • UNIX 철학과 작은 정리
    • 환경 커스터마이즈
    • 작고 가벼운 커널
    • 소문자 사용
    • 자연 보호
    • 침묵은 금
    • 병령 사고
    • 부품 협력
    • 90%의 해
    • 열등해야 뛰어나다
    • 계층 지향
  • 응집도
    • 응집도란 모듈에 포함된 기능의 순수함을 나타내는 척도로, 모듈의 강도를 측정하는 단위다
    • 응집도의 단계는 7단계다.
    • 단계가 높을수록(숫자가 클수록) 순수하고 강하며 좋은 모듈이다.
    • 1단계: 암합적 강도
      • 모듈 내 요소 간 특별한 관계가 인정되지 않는다
      • 암합이란 우연히 요소가 일치한다는 의미다
    • 2단계: 논리적 강도
      • 어떤 기능을 추상적으로 파악해서 모은 것이다
    • 3단계: 시간적 강도
      • 특정 시점에 연속해서 실행되는 여러 개의 기능을 하나의 모듈로 모은 것이다.
    • 4단계: 순서적 강도
      • 문제를 처리하기 위해 관계된 여러 개의 기능 중 몇 가지를 실행한다
    • 5단계: 연락적 강도
      • 기본적으로 순서적 강도의 특성을 갖는다
      • 순서적 강도와의 차이점은 모듈 내 기능 사이에서 데이터를 교환(연락)하거나 같은 데이터를 참조한다는 점이다.
    • 6단계: 정보적 강도
      • 특정 자료구조를 다루는 여러 개의 기능을 하나의 모듈로 모은 것이다.
    • 7단계: 기능적 강도
      • 모듈 내의 모든 명령이 하나의 역할(기능)을 실행하기 위해 서로 관련된 모듈로, 응집도가 가장 높은 모듈이다
  • 결합도
    • 결합도란 모듈끼리 갖는 관계의 밀접함을 나타내는 척도로, 어떤 결합의 굵기를 측정하는 단위다
    • 결합도의 수준은 6단계다.
    • 단계가 높을수록(숫자가 클수록) 관계가 약하고 느슨한 결합이며 좋은 모듈이라고 할 수 있다
    • 1단계: 내용 결합
      • 한 모듈과 다른 모듈이 일부를 공유하는 모듈 결합 방식
      • 다른 모듈 내의 외부에 선언되지 않은 데이터를 직접 참조하거나 명령의 일부를 공유하는 경우
    • 2단계: 공통 결합
      • 공통 영역에 정의된 데이터를 몇 개 모듈이 공동으로 사용하는 모듈 결합 방식
      • 공통 영역에 정의된 데이터란 이른바 전역 변수를 말한다
    • 3단계: 외부 결합
      • 외부에 선언된 데이터를 공유하는 모듈 결합 방식
      • 외부에 선언된 데이터란 예를 들면 public으로 선언된 변수를 말한다
    • 4단계: 제어 결합
      • 호출하는 모듈 쪽에서 호출받는 모듈의 제어를 지시하는 데이터를 파리미터로 넘겨주는 모듈 결합 방식
    • 5단계: 스탬프 결합
      • 공통 영역에 없는 자료구조를 2개의 모듈에서 교환하는 모듈 결합 방식
    • 6단계: 데이터 결합
      • 모듈 간의 인터페이스로 스칼라형 데이터 요소만을 파라미터로 교환하는 모듈 결합 방식
      • 모듈 A는 모듈 B의 입력으로 X를 넘겨주면 출력으로 Y를 받는다는 점만 알고 있다
    • 느슨한 결합을 지향하자
      • 데이터는 가능한 한 파라미터로 넘겨준다
      • 데이터는 가능한 한 전역 변수로 두지 않는다. 특정 시점에만 필요한 데이터라면 지역 변수로 두도록 한다
      • 넘겨주는 값에 따라 동작이 바뀌는 코드를 작성하지 않는다. 예를 들어 파라미터로 건네받는 플래그의 내용이 A라면 추가, D라면 삭제하는 식의 함수는 결합도가 강해진다
  • 직교성
    • 직교는 기하학에서 그래프의 좌표축과 같이 직각으로 교차하는 2개의 선분이 갖는 성질이다
    • 코드 간에는 독립성과 분리성을 갖도록 만든다
    • 2개 이상의 코드 덩어리가 있으면서 한쪽을 변경해도 다른 쪽에 영향을 주지 않는다면 해당 코드는 직교하고 있다
    • 직교하고 있는 코드는 변경에 강한 코드다
    • 장점
      • 생산성 향상
      • 위험 경감
  • 가역성
    • 가역이란 어떤 변화가 발생해도 특정 조건을 가하면 원래 상태로 돌아오는 성질
  • 코드의 구린내
    • 코드의 구린내란 코드 중에서 이해하기 어렵고, 수정하기 어렵고, 확장하기 어렵다고 느껴지는 부분
    • 프로그래머는 이런 구린내를 식별해 내서 적절한 코드로 개선해야 한다
    • 코드의 구린내 징후
      • 자주 보인다
        • 똑같은 코드가 여기저기 흩어져 있는 상태
      • 너무 길다
        • 함수가 너무 길어 스크롤을 몇 번이나 내려도 끝나지 않는 상태
      • 너무 크다
        • 모듈이 너무 컷거 관리 불능인 상태
        • 모듈이 너무 크다는 말은 해당 모듈이 담당하는 역할이 너무 크다는 뜻
      • 너무 많다
        • 모듈이 너무 많아서 관리 불능인 상태
        • 모듈이 크다는 이유로 지나치게 분해해서는 안 된다
      • 이름이 맞지 않는다
        • 이름과 실제 코드가 맞지 않는 상태
        • 이름은 중요하다
  • 기술적 부채
    • 문제 있는 코드는 '빚'이다
    • 프로그래밍의 2가지 길: 시간이 좀 걸리더라도 깨끗한 코드 or 신속하지만 지저분한 코드
    • 신속하고 지저분한 코드를 선택한다면 소프트웨어는 이른바 부채를 떠안는 셈이되는데 이를 기술적 부채라고 부른다
    • 기술적 부채는 코드에서 수정하기 어렵고 이해하기 어려운, 문제 있는 지저분한 코드 부분을 뜻한다
  • 프로그래머의 3대 미덕
    • 태만
      • 전체의 노력을 줄이기 위해 수고를 아끼지 않는 기질
      • 나중에 모두가 편해지도록 지금 유용한 코드를 작성한다
      • 반복 업무를 시스템화하자
      • 수작업에 관해서는 코드를 작성하고 툴을 만들어서 자동화 한다
    • 성급
      • 컴퓨터가 놀고 있는 것에 분노를 느끼는 기질
      • 일어날 수 있는 문제를 상정해서 업무를 하자
    • 오만
      • 천벌을 받을 정도로 넘치는 자존심을 지닌 기질
      • 높은 자존심을 갖고 남에게 내놓아도 부끄럽지 않은 코드를 작성한다
      • 남에게 부끄럽지 않게끔 작업하고 보수하자
  • 보이 스카우트 규칙
    • 코드는 자기가 왔을 때보다 깨끗이 하고 나서 자리를 떠나야 한다
    • 처음 코드를 작성한 사람이 누구인지와는 상관없이, 조금씩이라도 코드를 개선하려는 노력을 계속해야 한다
  • 성능 튜닝에 관한 금언
    • 프로그래밍에서는 빠른 코드보다 우선 바르고 읽기 쉬운 것에 주안점을 둔 좋은 코드를 작성하는 데 노력해야 한다
  • 비자아적 프로그래밍
    • 프로그래밍할 때는 자아를 떨쳐 버려야 한다
    • 자만과 자존심을 버리고 동료에게 협력을 구하도록 한다
    • 자신이 작성한 코드를 적극적으로 등료에게 보여주면서 개선점을 지적해 달라고 한다
    • 비자아적 프로그래밍의 십계
      • 자기 자신도 실수를 저지른다는 점을 이해하고 받아들인다
      • 작성한 코드는 자기 자신이 아니다
      • 아무리 끝까지 간 것 같아도 위에는 그 이상이 있다
      • 상담 없이 코드를 재작성하지 않는다
      • 자기보다 기술이 떨어지는 사람에게도 존경과 경의, 인내를 갖고 대한다
      • 세상에서 유일하게 변하지 않는 것은 변한다는 사실뿐이다
      • 진정한 권위는 지위가 아니라 지식에서 생겨난다
      • 신념을 위해 싸운다. 다만 패배는 깨끗이 수용한다
      • 방에 틀어박혀 있어서는 안 된다
      • 사람에게는 관대하고 코드에는 엄격하게, 사람이 아닌 코드를 비평한다
  • 한 걸음씩 조금씩
    • 프로그래밍은 한 번에 작은 하나만을 수행한다
    • 하나씩 조금씩 단차가 작은 계단을 올라가듯이 작업한다
    • 절대 한 번에 여러 가지 작업을 상대하지 말고 하나씩 처리한다
  • TMTOWTDI (There's more than one way to do it 방법은 하나가 아니다)
    • 다른 사람이 사용할 툴을 설계할 때는 달성하고자 하는 것의 수단을 여러 개 준비한다
    • 여기서 말하는 툴이란 프로그래밍 언어나 DSL, API를 가리킨다
  • 예광탄
    • 예광탄이란 빛을 발산함으로써 탄도의 궤적을 알 수 있게끔 만들어진 탄환을 말한다
    • 예광탄은 즉시 피드백을 가져다 준다
    • 프로그래밍에서의 예광탄이란 우선적으로 검증하고 싶은 부분을 선행적으로 프로그래밍하는 것이다
  • 계약에 의한 설계
    • 각각의 함수는 뭔가의 작업을 수행하는 것이다
  • 방어적 프로그래밍
    • 이렇게 될 것이다라고 결정짓지 말고 프로그래밍한다
    • 자동차의 방어 운전과 같은 사고방식이다
    • 외부 소스에서의 데이터 입력값을 확인한다
    • 함수의 입력 파라미터값을 확인한다
  • 개밥 먹기
    • 자기가 개발한 소프트웨어는 본인이 직접 사용해 봐야 한다
  • 고무 오리
    • 고무 오리는 일종의 디버깅 기법이다
    • 프로그래밍 중에 발생한 문제, 혹은 문제를 품고 있는 코드를 누군가에게 설명한다
    • 그러다 보면 문제의 원인을 스스로 깨닫고 자체 해결할 수 있을 때가 있다
  • 컨텍스트
    • 컨텍스트란 주위의 상황이나 배경을 뜻하며, 문맥이라고도 한다
    • 코드의 읽고 쓰기에 사용
    • 생각의 도구로 사용
  • 브룩스의 법칙
    • 일정이 늦어지고 있어 후반에 사람을 추가하면 오히려 지연이 한층 더 초래된다
  • 콘웨이의 법칙
    • 소프트웨어의 구조, 즉 아키텍처는 그것을 만든 조직을 반영한다
  • 깨진 유리창 법칙
    • 나쁜 설계, 잘못된 의사 결정, 나쁜 코드를 방치하면 그것이 아무리 작은 것이라도 소프트웨어 전체를 매우 단기간에 부패시킨다
  • 엔트로피 증가의 법칙
    • 엔트로피란 물리학 용어로 무질서한 정도를 나타낸다
    • 코드는 그대로 두면 한계를 뛰어넘을 만큼 무질서함이 증대된다
    • 코드의 부패 징후
      • 경직됨
        • 변경하기 어렵다
      • 깨지기 쉬움
        • 단 하나의 변경으로 인해 다른 많은 부분이 망가져 버리는 정도
      • 이식성 없음
        • 다른 환경으로 이식하기 어렵다
      • 다루기 어려움
        • 코드를 다루기 어려움과 개발 환경을 다루기 어려움이 있다
      • 복잡함
        • 불필요한 요소가 많음을 뜻한다
      • 반복
        • 똑같은 코드가 어러 번 반복해서 나타난다는 뜻이다
      • 불투명함
        • 코드를 이해하기 어렵다
  • 80:10:10의 법칙
    • 소프트웨어를 개발하면 사용자가 요구하는 것의 80%는 놀랄 만큼 단기간에 실현할 수 있다
    • 그러나 나머지 20% 중 10%는 실현은 가능하지만 상당한 노력이 필요하다
    • 더욱이 나머지 10%는 완전히 실현이 불가능하다
  • 조슈아 나무의 법칙
    • 사람은 이름을 아는 순간 그것이 보인다. 반대로 이름이 없으면(모르면) 그것은 보이지 않는다
  • 세컨드 시스템 증후군
    • 첫번째 버전을 배포한 프로그래머가 설계한 두번째 버전 소프트웨어는 해당 프로그래머가 설게하는 가장 위험한 버전이다
    • 두 번째 버전에는 기능을 너무 잔뜩 집어넣어 품질이 나쁘고, 기능의 사용성도 떨어지는 경향이 있다
  • 수레바퀴의 재발명
    • 이미 세상에 존재하는 수레바퀴를 일부러 수고를 들여 다시 한번 발명하는 것과 같은 쓸데없는 작업
    • 수레바퀴의 재발명을 피하고 본래 해야 할 작업에 주력하자
    • 코드를 작성하기 전에 똑같은 기능이 표준 라이브러리에 없는지, 오픈 소스 라이브러리에 없는지, 표준 프로토콜이 없는지를 반드시 확인하도록 한다
    • 수레바퀴를 재발명해야 될때
      • 비즈니스 목적
      • 학습 목적
  • 야크의 털깍기
    • 어떤 문제를 해결하려고 봤더니 다른 문제가 계속 나와 좀처럼 몸통, 즉 기본 문제(의 해결)에 도달하지 못하는 것이다
    • 야크의 털깍기는 기본적으로 피해 가야 한다

· 약 4분
karais89

유니티 IDE 선택에 대한 잡소리 입니다.

윈도우 환경에서는 두말 할 것 없이 visual stduio 쓰시면 됩니다. 모두가 인정하는 최고의 ide 입니다.

맥에서의 유니티 IDE 선택에 대한 이야기 입니다.

사실 초창기에는 어쩔 수 없이 mono IDE를 쓸 수 밖에 없었습니다.

일단 기본적으로 mono의 경우 맥에서는 한글 입력이 되지 않는 현상이 존재하며, 초창기 mono의 경우 화면 분할 또한 가능하지 않았습니다. 이러한 문제들 때문에 서브라임 텍스트를 사용한다던가 윈도우 환경을 가상 머신으로 돌려 비쥬얼 스튜디오를 사용하시는 분들도 계셨습니다.

사실은 제가 가장 추천해주고 싶은 ide는 visual stduio code 입니다. (ide라기 보다는 텍스트 에디터이지만..)

일단 가볍고, 자동 완성 기능 또한 준수하고, 디버깅 기능또한 제공되기 때문에 사실 제가 볼때는 가장 괜찮은 선택일 것 같습니다.

사실 맥에서 나온 visual stduio의 경우 자마린 기반이라. 제가 처음에 생각했던 멋진 모습의 ide가 아니라 실망을 많이 했던 기억이 있습니다.

그이외에 추천하는 툴은 젯브레인사의 Rider입니다.

일단 기본적으로 젯브레인사의 모든 ide는 유료 입니다.

트라이얼 버전이나 학생의 경우는 무료로 사용할 수 있으니 그 기간동안 관련 ide를 사용해 보시고 괜찮으시면 사용해 보는 것도 좋은 선택 인 것 같습니다.

가장 큰 장점은 제가 보기엔 크로스 플랫폼 지원인 것 같습니다.

윈도우와 맥에서 같은 환경에서 같은 ide로 작업하는 것 자체가 큰 메리트로 다가 왔습니다.

그리고 젯브레인사의 제품답게 리팩토링 관련 기능들이 강력한 것 같습니다.

또한 유저의 편의성을 생각하는 ide의 기능들이 눈에 띄었습니다.

예를들어 유니티 자체 함수의 경우 옆에 유니티 아이콘으로 표시해 주는 점.

또한 제일 신기했던 부분은 인보크나 스타트 코루틴에 스트링으로 함수를 호출해주는 부분이 있는데 그 부분 조차 리팩토링을 지원해 줘서 이름을 바꿀 수 있다는 점입니다.

어쨌든 저도 무료 기간동안은 계속해서 사용할 예정이고, 만족하면서 사용 중입니다.

한번 쯤 맥 환경에서 ide를 고민하시는 분들은 사용해 보시는 것을 추천 드립니다.

참조

· 약 11분
karais89

김포프님 C# 코딩 스탠다드

포프님이 올리신 C# 코딩 스탠다드의 번역 글입니다.

번역 자체는 구글 번역에서 이상한 부분은 제가 수정 하였습니다. 번역 자체의 문제가 있을 수 있습니다.

코딩 스탠다드는 코드 몽키 레벨에서는 왜 이렇게 작성했는지에 대한 설명을 할 필요도 없고 그냥 코딩 스탠다드에 주어진 내용 대로 코드를 짜면 된다고 합니다.

하지만 아래 45가지의 코딩 스탠다드에는 분명히 그렇게 해야 되는 이유가 존재 합니다.

꼭 아래의 코딩 스탠다드를 사용하여 코드를 작성하실 필요는 없습니다.

경험에 바탕을 둔 방법

  1. 읽기 좋은 코드가 우선(대부분의 경우 사용 설명서가 항상 문서화되어야 함)
  2. 그렇지 않은 이유가 있는 경우가 아니라면 IDE의 자동 형식 지정 방식을 따르십시오. (VisualStudio의 Ctrl+K+D)
  3. 기존 코드로부터 배우기

참조

이 코딩 스탠다드는 이러한 코딩 표준에 의해 영감을 받는다.

이름 지정 규칙 및 스타일

1. 클래스 및 구조체에 파스칼 케이스1 사용

class SomeClass;    
struct SomeStruct;

2. 지역 변수 이름과 함수 매개 변수에 카멜 케이스2 사용

void SomeMethod(int someParameter)
{
int someNumber;
}

3. 모든 메소드 이름은 파스칼 케이스 사용

public uint GetAge()
{
// function implementation...
}

4. 메소드 이름은 동사 + 명사 사용

public uint GetAge()
{
// function implementation...
}

5. non-public 메서드면 post fix로 "Internal"을 붙인다

Private uint GetAgeInternal()
{
// function implementation...
}

6. 상수는 ALL_CAPS_SEPARATED_BY_UNDERSCORE를 사용한다.

const int SOME_CONSTANT = 1;

7. namespaces는 파스칼 케이스를 사용한다.

namespace System.Graphics

8. boolean 변수 앞에는 b를 붙이고 프로퍼티에는 앞에 is를 붙인다.

bool bFired;    // for local variable
Private bool mbFired; // for private class member variable
Public bool IsFired { get; private set; }

9. 인터페이스 앞에는 I를 붙인다.

interface ISomeInterface 
{

}

10. enum 앞에는 E를 붙인다.

public enum EDirection
{
North,
South
}

11. private 멤버 변수 앞에 m을 붙입니다. 나머지 멤버 변수에는 파스칼 케이스를 사용하십시오.

Public class Employee
{
public int DepartmentID { get; set; }
private int mAge;
}

12. 반환 값이있는 메소드는 반환 된 값을 설명하는 이름을 가져야합니다.

public uint GetAge();

13. 설명적인 변수 이름을 사용하십시오. 예를 들어 루프에 사용되는 사소한 변수가 아니라면 i 또는 e 대신 index이나 employee이 될 수 있습니다.

14. 두개의 문자만 있는 경우 머리 글의 모든 문자를 대문자로 구분합니다.

public int ID { get; private set; }

15. 두개의 문자 이상인 경우 머리 글자로 된 첫 번째 문자 만 대문자로 표시하십시오.

public string HttpAddress { get; private set; }

16. getter setter 함수보다 프로퍼티를 선호해라.

이거 대신에:
public class Employee
{
private string mName;
public string GetName();
public string SetName(string name);
}

이렇게 사용해라:
public class Employee
{
public string Name {get; set;}
}

17. 4 개의 스페이스와 동일하게 탭을 사용해라

18. 로컬 변수가 사용되는 첫 번째 행에 최대한 가깝게 선언하십시오.

19. 새로운 줄에 항상 여는 중괄호 "{" 를 넣으십시오.

20. scope에 단 하나의 줄이 있어도 중괄호를 추가하십시오.

if (bSomething)
{
return;
}

21. 부동 소수점 값에 대한 정밀도 지정은 명시 적으로 double이 필요하지 않는 한 사용하십시오.

float f = 0.5F;

22. switch 문에는 항상 default가 있어야 합니다.

switch (number)
{
case 0:
...
break;
default:
break;
}

23. case 문에 코드가없는 경우를 제외하고는 switch case에 대한 fallthrough 설명을 추가하십시오.

switch (number)
{
 case 0:
   DoSomething();
   //fallthrough
 case 1:
   DoFallthrough();
   break;
 case 2:
 case 3:
   DoNotFallthrough();
break;
 default:
   break;
}

24. 스위치 문에서 default 문이 발생해야되지 않아야 되는 경우에는 항상 Assert(false)를 더해라. assert 구현에서, 이것은 릴리즈 빌드를위한 최적화 힌트를 추가 해라.

switch (type)
{
case 1:
...
break;
Default:
Debug.Fail("unknown type");
break;
}

25. 재귀 함수의 이름은 "Recursive"로 끝내라.

void FibonacciRecursive();

26. 클래스 변수와 메소드의 순서는 다음과 같아야합니다.

  1. public variables
  2. internal variables
  3. protected variables
  4. private variables
  5. public methods
  6. Internal methods
  7. protected methods
  8. private methods

27. 함수 오버로딩은 대부분의 경우 피해야합니다.

이거 대신에:
Anim GetAnim(int index);
Anim GetAnim(string name);

이렇게 사용해라:
Anim GetAnimByIndex(int index);
Anim GetAnimByName(string name);

28. 여러 개의 작은 클래스를 그룹화하는 것이 합리적이지 않으면 각 클래스는 별도의 소스 파일에 있어야합니다.

29. 파일 이름은 대문자와 소문자를 포함한 클래스의 이름과 동일해야합니다.

class Anim {}

Anim.cs

30. 너가 가지고 있는 주장에는 assert를 사용해라. (예, 모든 함수는 Debug.Assert( not null parameters) 를 가져야 한다.)

31. bigflag 열거 형의 이름은 Flags로 끝나야합니다.

public enum EVisibilityFlags
{
}

32. 기본 매개변수보다 오버로딩을 더 선호한다.

33. 기본 매개 변수가 사용되면 null, false 또는 0과 같은 자연스러운 상수로 제한하십시오.

34. 지역 변수 숨김은 허용하지 않는다.

public class SomeClass
{
public int Count {get;set;}
public void Func(int Count)
{
for (int count = 0; count != 10; ++count)
{
// Use Count
}
}
}

35. 항상 System.Collections의 컨테이너보다 System.Collections.Generic의 컨테이너를 사용하십시오. 순수 배열을 사용하는 것도 좋습니다.

36. var 키워드 대신 실제 타입을 사용하는 걸 선호합니다. Enumerator같은 경우에는 var를 사용할 수 있습니다.

37. 싱글톤 패턴이 아닌 static class를 사용해라.

38. async void 보다 async Task를 사용해라. async void는 오직 이벤트 핸들러에서만 사용해라.

39. 경계에서 외부 데이터의 유효성을 검사하고 데이터를 함수에 전달하기 전에 반환하십시오. 즉,이 시점 이후에 모든 데이터가 유효하다고 가정합니다.

40. 따라서 우리 함수 내부에서 예외를 던지지 마십시오. 이것은 경계에서만 처리되어야합니다.

41. public 함수에서는 특히 매개 변수에 null을 허용하지 않는 것이 좋습니다.

42. 만약 매개변수에 null을 사용해야 하는 경우라면, 매개변수 이름의 postfix로 OrNull을 붙이십시오.

43. 어떤 함수, 특히 public 함수에서는 null을 반환하지 않기를 바랍니다. 하지만 예외를 throw 하지 않도록 null을 반환해야 하는 경우가 있습니다.

44. 만약 함수에서 null을 반환해야 된다면, 함수 이름에 Postfix로 OrNull을 붙입니다.

public string GetNameOrNull();

45. 객체 initializer를 사용하지 말자. 대신에 명명 된 매개 변수와 함께 명시적 생성자를 사용합시다. 아래 두가지 예외 상황은 제외 합니다.

a. 오브젝트가 한 곳에서만 작성된 경우. (예를 들어, 1 회의 DTO)
b. 객체가 소유 클래스의 정적 메서드 내에서 만들어 질 때 (: 팩토리 패턴)

  1. 첫 단어를 대문자로 시작하는 표기법. 예) BackgroundColor, TypeName, PowerPoint
  2. 각 단어의 첫문자를 대문자로 표기하고 붙여쓰되, 맨처음 문자는 소문자로 표기함. 예) backgroundColor, typeName, iPhone

· 약 6분
karais89

프로그래밍 실력 향상 방법

관련 링크들 요약 및 정리

추후 관련 자료들이 더 있으면 추가할 예정.

프로그래밍 스킬을 향상시키는 10가지 방법

  1. 새로운 프로그래밍언어를 배워라.
    • Lisp, Forth, PostScript or Factor, J, Haskell, Prolog, Erlang 등
  2. 좋은 프로그래밍 책을 읽어라.
    • The Art of Computer Programming
    • Structure and Interpretation of Computer Programs (SICP)
    • A discipline of Programming or the famous dragon book.
  3. 오픈소스 프로젝트에 참여하라
    • GitHub, Sourceforge, gitorious, BitBucket or Ohloh.
  4. 프로그래밍 퍼즐(문제)을 풀어라.
  5. 프로그램을 작성하라.
  6. 코드를 읽고 공부하라.
    • Linux Kernel (리눅스 커널)
    • MINIX3는 학습하기에 아주 좋은 운영체제 입니다.
  7. 프로그래밍 관련 웹 사이트 혹은 블로그를 방문해라.
  8. 프로그래밍에 대한 블로그를 작성하라.
    • Q&A같은 것을 통해 질문을 받고 답을 해주기 바랍니다.
    • 튜토리얼을 작성해보세요.
  9. 로우레벨 프로그래밍을 배워라.
    • C
    • assembler
    • 컴퓨터의 기원
    • 운영체제
    • 임베디드 시스템
    • 운영체제 드라이버 개발
  10. 프로그램이 작동하지 않는가? 도움을 받으려 하지 말고 스스로 생각하여라.

동기에게 보내는 편지 : 프로그래밍 실력을 향상 시키는 방법

초보에서 고수로 가는 길.

  1. Code Complete 2/E
  2. Refactoring
  3. 프로그래밍 수련법
  4. 실용주의 프로그래머
  5. 생각하는 프로그래밍

위의 책은 순서에 상관없이 읽어야 되는 책 입니다. 3번부터 보고 다른 것을 읽는 것을 추천 합니다.

게임 프로그래머 실력향상법 자료조사

  1. GitHub와 포트폴리오
    • 오픈 소스 프로젝트 참여 및 자신의 프로젝트 제작
  2. 세미나
  3. 게임 개발자 커뮤니티
  4. 기초부터 단단히
    • 알고리즘
    • 자료구조
    • C#
    • Unity
    • 컴퓨터 그래픽스
  5. 게임 개발 서적 추천
    • C++ 기초 플러스
    • 뇌를 자극하는 C# 5.0 프로그래밍
    • 유티티 4 게임 개발의 정석
    • 따라 하면서 배우는 NGUI 유니티 2D 게임 프로그래밍
    • 유니티 네트워크 프로그래밍
    • 좋은 프로그램을 만드는 핵심 원리 25가지
    • 성공과 실패를 결정하는 1%의 프로그래밍 원리
    • 게임 프로그래밍의 정석
    • 리팩토링
    • Head First Design Pattern
    • Game Programming Gems 시리즈
    • 실용주의 프로그래머
    • 위대한 게임의 탄생 시리즈
    • CODE COMPLETE
    • Debug It! 실용주의 디버깅
    • Effect C++
    • 셰이더 프로그래밍 입문
    • DirectX9를 이용한 3D Game 프로그래밍 입문
    • 프로그래밍 면접 이렇게 준비한다
    • 익스트림 프로그래밍
    • 열혈 C 프로그래밍
    • 3D 게임 프로그래밍
    • Programming Game AI by Example
    • 게임 프로그래머를 위한 기초 수학과 물리
    • STL 튜토리얼 레퍼런스 가이드
    • 나는 프로그래머다.

관련 글