프로그래밍의 정석 요약
책에서의 용어 설명
- 모듈연관성이 높은 코드를 한데 묶었다는 의미에서 클래스, (함수나 변수를 모은 하나의) 파일, 컴포넌트, 부품, 라이브러리라는 용어도 있는데, 이 용어들을 모두 포함해서 모듈이라고 부른다.
- 함수나 변수를 어떤 책임 단위로 묶어낸 것은 모듈로 통일한다.
- 함수루틴, 함수, 프로시저, 메시지, 메서드, 멤버 함수 등 용어는 세부적으로 나뉘는데, 이 용어들은 모두 포함해서 함수라고 한다.
- 코드 일부를 떼어내어 호출할 수 있게 만든 것은 함수로 통일한다.
책에서의 참고 서적
- 맨먼스 미신
- 소프트웨어 개발은 어째서 어려운가?-맨먼스 미신을 뛰어넘어 (국내 미출간)
- 소프트웨어 공학의 사실과 오해 - 우리가 미처 알지 못한
- CODE COMPLETE - 소프트웨어 구현에 대한 실무서
- 클린 소프트웨어
- 프로그래머가 알아야 할 97가지
- 도메인 주도 설계
- 익스트림 프로그래밍
- 실용주의 프로그래머
- Art of UNIX Programming
- 소프트웨어 아키텍트가 알아야 할 97가지
- 능률적인 프로그래머 - 프로그래머 생산성의 비밀
- 레거시 코드 활용 전략
- 지속적인 통합 - 소프트웨어 품질을 높이고 위험을 줄이기
- 좋은 코드를 작성하는 기술-읽기 쉽고 유지보수가 쉬운 프로그래밍 작성법
- 구체와 추상-세계가 달리 보이는 지성의 구조(국내 미출간)
- 패턴, Wiki 그리고 XP - 시간을 초월한 창조의 원칙
- EXTREME PROGRAMMING INSTALLED - XP 도입을 위한 실전 입문
- 애자일 프랙티스 - 빠르고 유연한 개발자의 실천 가이드
- CODE CRAFT - 뛰어난 코드 작성을 위한 실천 지침
- 커누스 교수의 프로그래밍론(국내 미출간)
- 프로젝트 관리자가 알아야 할 97가지
- 읽기 쉬운 코드가 좋은 코드다 - 더 나은 코드를 작성하는 간단하고 실전적인 테크닉
- 켄트 백의 스몰토크 가이드와 패턴 - 심플한 디자인을 위한 핵심 노트(국내 미출간)
- 켄트 백의 구현 패턴
- 패턴을 활용한 리팩토링
- 객체지향 입문 제2판 - 원칙과 개념(국내 미출간)
- HEAD FIRST DESIGN PATTERNS
- UML과 디자인 패턴 활용
- 프로그래밍의 모든 것 - C의 창시자 브라이언 커니건
- 알기 쉬운 디자인 패턴
- 마쓰모토 유키히로의 코드의 세계 - 최간 프로그래머가 되는 14가지 사고방식
- 네이밍의 규칙과 비법(국내 미출간)
- 클린 코드
- 커누스 교수의 프로그래밍론(국내 미출간)
- 패턴 지향 소프트웨어 아키텍처
- 조직 패턴(국내 미출간)
- UNIX MAGAZINE Classic with DVD(국내 미출간)
- 코딩을 지탱하는 기술 - 원리로 깨우치는 프로그래밍 기법
- 구체와 추상 - 세계가 달라 보이는 지성의 구조(국내 미출간)
- 관점 지향 프로그래밍 입문 - Java 객체지향에서 AspectJ 프로그래밍으로(국내 미출간)
- 객체지향 프로그래밍 입문(국내 미출간)
- 객체지향 프로그래머가 다음으로 읽는 책 - 스칼라로 배우는 함수뇌 입문(국내 미출간)
- UML을 활용한 객체지향 분석 설계
- 비기능 요구사항 정의 가이드라인(국내 미출간)
- 테크니컬 엔지니어 정보 보안 표준 교분(국내 미출간)
- 소프트웨어 품질 지식 체계 가이드 - SQuBOK Guide 제2판(국내 미출간)
- 어떻게 문제를 풀 것인가 - 수학적 사고방식
- UNIX라는 사고방식 - 설계 사상과 철학(국내 미출간)
- 효과적 프로그램 개발 기법(국내 미출간)
- 소프트웨어의 복합 구조화 설계(국내 미출간)
- 웹 개발자를 위한 웹을 지탱하는 기술 - HTTP, URI, HTML 그리고 REST
- RESTful 웹 서비스 - 웹 서비스의 진화
- 엔터프라이즈 애플리케이션 아키텍처 패턴 - 엔터프라이즈 애플리케이션 구축을 위한 객체지향 설계의 원리와 기법
- 관계형 데이터베이스 실전 입문 - 원리부터 배우는
- Java 언어로 배우는 리팩토링 입문
- 리팩토링 - 코드 품질을 개선하는 객체지향 사고방식
- 애자일 개발의 예술 - 조직을 성공으로 이끄는 익스트림 프로그래밍(국내 미출간)
- 코가이 단의 시스템 진화론(국내 미출간)
- Perl 프로그래밍
- THE ART OF PROJECT MANAGEMENT - 마음을 움직이는 프로젝트 관리
- Effective Java
- 프로그래밍 심리학
- 성공하는 사람들의 7가지 습관
- 테스트 주도 개발
- 사상 최강의 논리 퍼즐 - 핵심을 간파하는 힘을 기르는 60문제(국내 미출간)
- 효과적인 프로그램 개발 기법(국내 미출간)
- 성공적인 소프트웨어 개발 프로젝트를 위한 실용 가이드
- 객체지향 입문 제2판 - 원칙과 개념(국내 미출간)
- 조엘 온 소프트웨어 - 유쾌한 오프라인 블로그
- 시스템 사고 입문(국내 미출간)
- 니코마코스 윤리학
- 입문 철학으로서의 불교(국내 미출간)
- 포커스 리딩 - 한 권에 10분 속도로 열 배의 효과를 내는 장점 일색 독서술(국내 미출간)
- 안티패턴 - 소프트웨어 위독 환자 구출(국내 미출간)
- 린 소프트웨어 개발과 조직 개혁(국내 미출간)
- 불가사의 심리학 - 알기 쉽게 배우는 과학적 사고의 기술
- 엔트로피를 둘러싼 모험 - 초보자를 위한 통계 열역학(국내 미출간)
- 디자이너가 아닌 사람들을 위한 디자인북
- 교양으로서의 성서(국내 미출간)
- Code Simplicity - 소프트웨어 간결성을 지키는 사실과 법칙, 그리고 진리
- 프로그래머, 열정을 말하다
원리 원칙 리스트
- 프로그래밍에 은제 탄환은 없다
- 프로그래밍에 마법 같은 해결책은 없다.
- 코드는 설계서다
- 코드는 반드시 변경된다
- 코드가 변경된다는 사실은 코드를 작성할 때 다양한 판단, 선택, 결단을 하는 데 있어서 최우선으로 고려해야 한다.
- 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개의 분리된 부분으로 구성한다.
- 인터페이스 파트 : 모듈이 가진 기능을 정의하고 모듈의 사용 방법을 정하는 부분 클라이언트에서 접근할 수 있는 함수의 원형으로 구성된다.
- 구현 파트 : 구현 파트란 모듈이 가진 기능을 실현하는 코드 부분. 모듈이 내부에서 사용하는 로직과 데이터가 포함된다. 구현 파트는 클라이언트에서 접근할 수 없다.
- 사용자는 인터페이스만 알면 된다.
- 모듈은 인터페이스 파트와 구현 파트 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%는 완전히 실현이 불가능하다
- 조슈아 나무의 법칙
- 사람은 이름을 아는 순간 그것이 보인다. 반대로 이름이 없으면(모르면) 그것은 보이지 않는다
- 세컨드 시스템 증후군
- 첫번째 버전을 배포한 프로그래머가 설계한 두번째 버전 소프트웨어는 해당 프로그래머가 설게하는 가장 위험한 버전이다
- 두 번째 버전에는 기능을 너무 잔뜩 집어넣어 품질이 나쁘고, 기능의 사용성도 떨어지는 경향이 있다
- 수레바퀴의 재발명
- 이미 세상에 존재하는 수레바퀴를 일부러 수고를 들여 다시 한번 발명하는 것과 같은 쓸데없는 작업
- 수레바퀴의 재발명을 피하고 본래 해야 할 작업에 주력하자
- 코드를 작성하기 전에 똑같은 기능이 표준 라이브러리에 없는지, 오픈 소스 라이브러리에 없는지, 표준 프로토콜이 없는지를 반드시 확인하도록 한다
- 수레바퀴를 재발명해야 될때
- 비즈니스 목적
- 학습 목적
- 야크의 털깍기
- 어떤 문제를 해결하려고 봤더니 다른 문제가 계속 나와 좀처럼 몸통, 즉 기본 문제(의 해결)에 도달하지 못하는 것이다
- 야크의 털깍기는 기본적으로 피해 가야 한다