취미/개발서적

전문가를 위한 C++ 4판 CHAPTER 3

게임 개발 2024. 5. 17. 00:20

 
아무래도 시중에 나온 번역본은 저작권 문제도 있을 것이고,
영어 공부도 할 겸 해당 서적을 직접 번역하여 작성하는 것으로 결정했습니다.
해당 게시글은 professional C++. 4th Edition 를 번역하였습니다.
번역 과정에서 의역이 들어갔음을 참고바랍니다.
 

Coding with Style 코딩 스타일 

 
해당 챕터에서 배우는 것들은 무엇인가?
 
1. 코드의 문서화의 중요성과 당신이 사용할 수 있는 주석 스타일이 무엇인지?
2. 코드 분해란 무엇이고, 코드 분해는 프로그래머가 어떻게 사용하는가?
3. 명명 규칙이란 무엇인가?
4. 포매팅 (형식 지정) 규칙이란?
 
만약 몇시간 씩 코드를 작성해가고 있다면,
그 시간 내내 코드에 대한 책임을 져야 할 것이다.
주어진 작업을 완료해가며 코드를 작성하는 것은 프로그래머의 작업 중 일부일 뿐이다. 
결국에는 코딩의 기초를 배우고 작성하는 것은 누구나 할 수 있는 일이고,
진정한 달인이 되려면 코딩 스타일을 제대로 잡아가는 것을 알아야 한다.
 
그러니 해당 챕터에서는 좋은 코드를 만드는 방법에 대해서 알아보자.
그 과정에서 우리는 C++에 대한 몇 가지 접근 방식을 알 수 있을 것이다.
이 말을 좀 더 쉽게 풀어보자.
 
독자분들이 코드를 짜다가 알게되었을진 모르겠지만,
당연하게도 단순히 코드 스타일을 변경하면 코드가 매우 다르게 보일 수있다.
 
예를 들어서, Windows 프로그래머가 작성한 C++ 코드는 
Windows 규칙을 사용하여 고유한 스타일을 가지는 경우가 많다.
 
이는 즉 맥 OS를 기반으로 하는 프로그래머가 쓴 C++를 보면 완전히 다른 언어와 같이 느껴질 것이다.
이렇게 몇 가지 다른 코딩 스타일에 노출되면
C++ 소스 파일을 열 때 가라앉는 듯한 막막한 느낌을 피할 수 있다.
 

보기 좋은 것의 중요성 (THE IMPORTANCE OF LOOKING GOOD)

 
문체에 유의하며 "좋은" 코드를 작성하려면 시간이 필요하다.
십중팔구 채찍질 받으면서
더러운 코드를 상관하지 않고 시간에 쫒기며 XML 파일 프로그램을 작성한다면,
후자보다는 많은 시간이 소요되지는 않을 것이다.
 
기능적인 분해, 적절한 코멘트, 깨끗한 구조로 동일한 프로그램을 작성하는 것이
위 경우보다 더욱 시간이 소요될 것이다.
 
근데 후자가 과연 가치가 있을까?
미래 유지보수를 생각하면 가치가 있다.
새로운 인턴이 들어와서 전자의 코드를 가지고
점점 더 엉망이 된 웹 애플리케이션 코드에 직면했다고 가정해보자.
이 불쌍한 인턴은 어떻게 해당 코드를 기반으로 속도를 낼 수 있을까?
이는 비단 나 자신도 나중에 봤을 때 기본로직조차 기억이 안날 수도 있다.
후자의 경우인, 잘 쓰여진 코드는 읽고 이해하기 쉽기 때문이 이러한 문제를 피하도록 만든다.
 

좋은 코드 스타일의 요소 Elements of Good Style

코드를 "양식적으로" 좋게 만드는 코드 스타일의 특성을 열거하는 것은 쉽지만은 않다.
시간이 지나면서 개개인 별로 마음에 드는 코드 스타일을 찾을 수 있고,
다른 사람들이 작성한 코드에서 유용한 기술을 발견하기도 할 것이다.
어쩌면 더 중요한 것은 피할 것을 알려주는 끔찍한 코드를 접하게 될 수도 있다.
이처럼 좋은 코드 스타일에 대한 기준에 대한 갑론을박은 피할 수 없을 것이다.
 
하지만, 좋은 코드에 대해서 탐구하는 몇 가지 보편적인 원칙을 말해보겠다.
 
1. 문서화
2. 코드 분해
3. 명명 규칙
4. 언어 사용
5. 포매팅
 

코드의 문서화 DOCUMENTING YOUR CODE

 
프로그래밍을 언어로 접근해보자,
프로그래밍이란 언어 문맥 안에서 문서화란 무엇일까? 
일반적으로 소스 파일에 포함된 주석을 나타낸다.
주석은 코드 제작자가 머리 속에서 무슨일이 있었는 지를
세상에 표현할 수 있는 하나의 기회이다.
즉, 코드만으로는 뚜렷히 알기 쉽지 않았던 것을 설명해 줄 수 있다는 것이다.
 
 

주석을 작성하는 이유 (Reasons to Write Comments)

 
주석을 다는 것은 좋은 생각인 것은 분명해 보이지만,
왜 당신의 코드에 주석을 달 필요가 있는지 잠깐 하던 일을 멈추고 깊게 생각해본적이 있는가?
때때로 프로그래머들은 주석이 왜 중요한지 충분히 이해하지 못한 채 주석의 중요성을 인정하곤 한다.
이러한 몇 가지 이유들을, 해당 챕터에서 탐구해보자.
 

사용법을 알려주는 주석 (Commenting to Explain Usage)

주석을 사용하는 한가지 이유는,
어떻게 클라이언트가 코드와 상호작용 해야하는 지를 설명하기 위해서다.
일반적으로, 개발자는 함수가 수행하는 단순히 기본적인 것들인
즉 함수의 이름, 반환 값의 타입, 파라미터의 이름과 타입과 같은 것을 이해해야만 한다.
그러나, 이 모든 것이 코드만으론 후에 유지보수하는 개발자가 이해하도록 표현할 수는 없다.
코드를 읽는 사람은 함수의 사전 또는 사후 조건을 설명한 주석을 필요로 하곤 한다.
예외처리 역시 함수를 던지는 조건들 또한 때로는 반드시 주석안에 해당 설명을 기술해야 한다.
이 책의 저자의 생각은,
만약 정말로 유용한 정보인 경우에만 주석을 추가해야 한다고 주장한다.
 
따라서, 오직 함수의 주석이 필요한지 아닌지는 개발자의 결심에 달려있다.
숙련된 개발자들은 이러한 결정은 문제가 없지만,
숙련되지 않은 개발자는 언제나 옳은 결정을 내리진 못했을 것이다.
그렇기 때문에 일부 기업들은 반드시 공개적으로 이해하기 쉬운 주석을
각각의 헤더 파일에 함수 또는 메서드 규칙을
주석으로 설명하도록 명확히 제시하도록 하는 규칙을 가지고 있다.
일부 조직들은 여기서 더 나아가 각 용도를 담은 주석 리스트를 공식적인 문서화한다.
 
주석은 소통할 수 있는 언어로 개발자가 코드로 설명하지 못했던 것들을 설명할 기회를 주곤한다.
예를들어, 만약 openDatabase() 함수가 아직 불러지지 않아서,
데이터 베이스 객체의 saveRecord() 메소드가 예외처리로 throw를 발생시키는 것을
C++ 코드로 설명할 방법은 없다.
그러나 주석은 완벽하게 이러한 것들을 규정해준다.
다음은 이러한 예시 코드이다.
 
<예시 코드> 

/*
* This method throws a "DatabaseNotOpenedException"
* if the openDatabase() method has not been called yet.
*/
int saveRecord(Record& record);

 
C++ 언어는 메서드의 반환 유형을 지정하도록 프로그래머에게 억지로 강요하지만,
이렇게 반환된 값이
실제로 무엇을 나타내는지에 대한 것은 프로그래머에게 친절히 알려주지만은 않는다.
예를 들어, saveRecord() 메소드 선언으로 int을 반환한다는 것을 나타내곤 하지만,
그 코드를 읽는 클라이언트들은 int의 의미를 알지 못할 것이다.
주석은 이러한 의미를 설명해준다.
 
<예시 코드>

/*
* Returns: int
* An integer representing the ID of the saved record.
* Throws:
* DatabaseNotOpenedException if the openDatabase() method
has not
* been called yet.
*/
int saveRecord(Record& record);

 
앞서 언급한 바와 같이,
모든 함수에 대해 어느정도 형식이 잡힌 문서화를 요구하는 몇몇 기업도 있다.
다음 예시 코드는
saveRecord()메서드를 예시로 위 상황에 대한 주석 스타일을 구현한 것이다.
 
<예시 코드>

/*
* saveRecord()
*
* Saves the given record to the database.
*
* Parameters:
* Record& record: the record to save to the database.
* Returns: int
* An integer representing the ID of the saved record.
* Throws:
* DatabaseNotOpenedException if the openDatabase() method
has not
* been called yet.
*/
int saveRecord(Record& record);

 
 
그러나, 개인적으로 저자는 이러한 주석 스타일을 추천하지는 않는다.
함수 이름은 그 자체로 설명이므로 처음 두 행은 완전히 생략할 수 있다.
매개변수와 대한 설명은 예외 처리에 대한 주석이므로 따라서 생략해서는 안된다.
반환형도 생략은 할 수 있지만,
saveRecord 함수 버전의 반환형 int는
범용 타입을 리턴하므로 이 타입이 구체적으로
어떤 값을 표현하는지에 대해 문서에 남기는 것이 좋다.
특히 구체적으로 RecordID를 나타내므로 따라서 생략하지 않는 것이 더 나은 설계이다.
그러면 리턴 타입에 대한 주석을 따로 달 필요가 없다.
RecordID는 int 타입 데이터 멤버 하나만 가진 단순한 클래스로 만들 수도 있지만
나중에 필요에 따라 데이터 멤버를 추가해서 정보를 더 많이 담을 수 있다.
다음은 저자가 권장하는 코드 스타일의 예시이다.
 
<예시 코드>

/*
* Throws:
* DatabaseNotOpenedException if the openDatabase() method
has not
* been called yet.
*/
RecordID saveRecord(Record& record);

 

Note

만약 독자의 회사 코딩 가이드라인에 정해진 함수 주석 방식이 정해지지지 않았다면,
상식선의 센스를 발휘해서 적절히 주석을 쓰길 바란다.
함수의 이름, 리턴값의 타입, 매개변수의 이름과 파라미터가 명확하지 않을 경우에만
주석으로 남기도록 하자.

 
때로는 함수에 전달할 매개변수나 함수가 리턴하는 값이
거의 모든 종류의 정보를 전달할 수 있을 정도로 광범위하다. 
이러한 경우 독자는 확실히 문서화 작업을 통해서 타입을 정확하게 명시할 필요가 있다.
(아까 반환형int와 같이 해당 타입이 정확히 가리키는 값이 무엇인지 말이다.)
예를 들어 윈도우의 메시지 핸들러는 두 개의 
이 Param은 LPARAM 과 WPARAM을 받아들여서 LRESULT라는 결과 값을 반환할 수 있다. 
이 세 가지 타입은 사용자가 원하는 것을 전달하는 어떤 값의 제한없이 사용할 수는 있지만,
Param의 유형을 바꿀 순 없다.
그러므로,
간단한 정수값이나 어떤 특정 객체에 대한 포인터를 전달하려면
타입 캐스팅(형변환)을 사용하면 된다.
다음 코드와 같이 말이다.

* Parameters:
* WPARAM wParam: (WPARAM)(int): An integer representing...
* LPARAM lParam: (LPARAM)(string*): A string pointer
representing...
* Returns: (LRESULT)(Record*)
* nullptr in case of an error, otherwise a pointer to a
Record object
* representing...

 
 

복잡한 코드를 위한 주석 Commenting to Explain Complicated Code

좋은 주석은 실제 코드 안에서도 중요하다.
사용자의 입력을 처리하고 결과를 콘솔에 출력하는 간단한 프로그램에서는
모든 코드를 읽고 이해하는 것이 아마도 쉬울 것이다.
그러나 전문적인 서계에서는 알고리즘이 복잡하거나
단순히 살펴보는 것만으로는 이해하기 어려운 코드를 작성해야 할 때가 종종 있다.
다음에 나오는 코드를 고려해 보자.
이 코드는 잘 작성되었지만, 그것이 무엇을 하는지 즉시 이해하기 어려울 수 있다.
이 알고리즘을 이전에 본 적 있다면 알아볼 수도 있겠지만,
처음 본 사람이라면 이 코드가 어떻게 작동하는지 이해하지 못할 가능성이 높다.
 

void sort(int inArray[], size_t inSize)
{
	for (size_t i = 1; i < inSize; i++) {
		int element = inArray[i];
		size_t j = i - 1;
		while (j >= 0 && inArray[j] > element) {
			inArray[j+1] = inArray[j];
			j--;
		}
		inArray[j+1] = element;
	}
}


 더 나은 접근 방식은 사용된 알고리즘을 설명하는 주석과
(루프) 불편 조건을 문서화 하는 것이다.
불변 조건( Invariants  = 프로그램이 올바르게 동작하기 위해 특정 시점에 반드시 만족해야하는 조건)
코드 조각의 실행 중,
예를 들어 루프가 반복되는 동안 항상 참이여야 하는 조건을 말한다.
예를 들어 앞에 나온 코드에 다음과 같이 주석을 추가할 수 있다.
먼저 상단에 알고리즘을 개략적으로 설명하는 주석을 달고,
코드 중간에 혼란스러울 수 있는 특정 라인에는 문장 속에
인라인 주석(inline comment = 코드 사이 사이에 들어가는 주석)을 달았다.
 

/*
* Implements the "insertion sort" algorithm. The algorithm
separates the
* array into two parts--the sorted part and the unsorted part.
Each
* element, starting at position 1, is examined. Everything
earlier in the
* array is in the sorted part, so the algorithm shifts each
element over
* until the correct position is found to insert the current
element. When
* the algorithm finishes with the last element, the entire
array is sorted.
*/
void sort(int inArray[], size_t inSize)
{
	// Start at position 1 and examine each element.
	for (size_t i = 1; i < inSize; i++) {
		// Loop invariant:
		// All elements in the range 0 to i-1 (inclusive)
		are sorted.
			int element = inArray[i];
		// j marks the position in the sorted part after which
		element
			// will be inserted.
			size_t j = i – 1;
		// As long as the current slot in the sorted array is
		higher than
			// element, shift values to the right to make room for
			inserting
			// (hence the name, "insertion sort") element in the
			right position.
			while (j >= 0 && inArray[j] > element) {
				inArray[j + 1] = inArray[j];
				j--;
			}
		// At this point the current position in the sorted
		array
			// is *not* greater than the element, so this is its new
			position.
			inArray[j + 1] = element;
	}
}

 
새로운 코드는 확실히 더 이전보다 장황해지지만 정렬 알고리즘을 모르는 사람도
주석만 보고 쉽게 이해할 수 있다.
 

Commenting to Convey Meta-information(메타 정보를 제공하는 주석 달기)

 
주석을 사용하는 또 다른 이유는 코드 자체를 보다 가능한 더 높은 수준의 정보를 제공하기 위해서이다.
이러한 메타 정보는 (meta-information) 코드의 구체적인 동작에 대해서는 표현하지 않고,
코드 생성에 대한 세부사항만 표현한다.
예를 들어 현재 팀에서 코드 작성자를 메타 정보에 담아 관리할 수 있다.
또한 코드에서 인용하는 외부 문서나 다른 코드도 메타 정보로 표현할 수 있다.
 
다음 예제에서느 작성자, 작성 시기, 작성자가 지정한 특정 기능을 포함한
여러 메타 정보 인스턴스를 보여준다.
또한 코드 라인에 해당하는 버그 번호나 나중에
코드에서 발생할 수 있는 문제를
다시 확인하라는 알림과 같은 메타 데이터를 표현하는 인라인 주석을 달았다.
 

/*
* Author: marcg
* Date: 110412
* Feature: PRD version 3, Feature 5.10
*/
RecordID saveRecord(Record& record)
{
if (!mDatabaseOpen) {
throw DatabaseNotOpenedException();
}
RecordID id = getDB()->saveRecord(record);
if (id == -1) return -1; // Added to address bug #142 –
jsmith 110428
record.setId(id);
// TODO: What if setId() throws an exception? – akshayr
110501
return id;
}

 

change-log(변경 내역)는 각 파일의 시작 부분에 포함될 수 있다.
다음은 이러한 change-log(변경 내역)의 가능한 예를 보여준다.
 
/*
* Date | Change
*----------+--------------------------------------------------
* 110413 | REQ #005: <marcg> Do not normalize values.
* 110417 | REQ #006: <marcg> use nullptr instead of NULL.
*/
 
 
WARNING

24장에서 자세히 살펴보겠지만, 소스 코드 관리 솔루션을 사용할 때는
앞의 예제에서 주석으로 표현한 모든 메타 정보(TODO 제외)를 표현하지 않는 것이 좋다
(참고로 소스 코드 관리 솔루션은 반드시 사용하기 바란다).
이 솔루션은 리버전 날짜와 작성자에 대한 주석을 달아줄 뿐만 아니라
제대로 사용한다면 매번 수정할 때마다 변경 요청 및 버그 리포트를 인용하는 주석도 달 수 있다.
또한 변경 요청 또는 버그 픽스가 발생해서 체크인하거나 커밋할 때마다
작업한 내용을 설명하는 주석을 별도로 작성해야 한다.
이런 시스템을 활용할 때는 메타 정보를 직접 관리할 필요가 없다.

 
저작권 문구도 메타 정보로 표현한다.
종종 어떤 회사들은 소스 파일마다 항상 맨 앞에 저작권 문구를 적도록 정해둔다.
주석을 신경쓰다 보면 과도하게 달기 십상이다.
좋은 접근 방식은 어떤 유형의 주석이 가장 유용한지 집단 내 논의하여
공동 표준 특정한 코딩 스타일을 정하고 그에 따르는 것이 좋다.
예를 들어, 그룹의 한 구성원이
"TODO" 주석을 아직 작업이 필요한 코드라는 것을 나타내기 위해 사용하지만,
누군가가 이 관례를 모른다면,
이 코드에 대한 주석 규칙을 알지 못해 주의가 필요한 코드를 지나칠 수 있다.
 
 

Commenting Styles (주석 스타일) 

 
각 조직은 코드 주석에 대한 다른 견해를 가지고 있다.
일부 환경에서는 코드에 공통된 문서화 기준을 제공하기 위해
특정 스타일을 의무하기도 한다.
다른 경우에는 주석의 양과 스타일을 프로그래머에게 전적으로 맡기기도 한다.
다음 예제는 주석을 다는 여러 가지 접근 방식을 보여준다.
 

문장 단위 주석 ( Commenting Every Line )

문서화에 소홀하지 않는 한 가지 방법은 모든 문장에 주석을 작성하는 것이다.
이렇게 문장마다 주석을 작성하면 자연스레 꼭 필요한 코드만 작성하게 된다.
하지만 코드 전체를 이렇게 주석으로 도배하면 복잡하고 지저분해보일 뿐만 아니라
프로그래밍이 단순 노동으로 전락해버릴 수 있다.
다음 예를 보면 주석으로 작성하지 않아도 될 내용까지 주석에 넣었다.
 

int result; // Declare an integer to hold the result.
result = doodad.getResult(); // Get the doodad's result.
if (result % 2 == 0) { // If the result modulo 2 is 0 ...
    logError(); // then log an error,
}
else { // otherwise ...
    logSuccess(); // log success.
} // End if/else
return result; // Return the result

 
이 코드의 주석을 살펴보면 각 라인이 무엇을 의미하는지 이야기하듯 쉽게 설명하고 있다.
하지만 이 주석은 전혀 쓸모없다.
C++의 기본을 갖춘 사람이라면 굳이 이렇게 설명하지 않아도 쉽게 알 수 있기 때문이다.
예를 들어 다음 문장을 보자.
 

if (result % 2 == 0) { // If the result modulo 2 is 0 ...

 
이 문장은 단지 코드를 풀어쓰기만 했다. 
result 값에 모듈로 2 연산을 적용한 이유에 대해서는 한마디도 없다.
이를 좀 더 개선하면 다음과 같다.
 

if (result % 2 == 0) { // If the result is even ...

 
2에 대한 모듈로 연산을 사용한 이유가 결과가
짝수인지 검사하기 위해서라는 추가적인 정보가 들어갔다.
물론 프로그래머라면 대부분 굳이 주석을 보지 않아도 충분히 알 수 있는 내용이다.
 
더 나은 방법은 한눈에 들어오지 않는 표현식을 그대로 적지 말고
이해하기 쉬운 이름으로 된 함수로 바꾸면 좋다.
그러면 코드 자체가 문서의 역할을 하기 때문에
그 함수에 대한 주석을 따로 달 필요가 없고, 코드 재사용성도 높아진다.
예를 들어 다음과 같이 isEven()이란 이름으로 함수를 재정의할 수 있다.
 

// Calculate the doodad. The start, end, and offset values come from the
// table on page 96 of the "Doodad API v1.6".
result = doodad.calculate(kStart, kEnd, kOffset);
// To determine success or failure, we need to bitwise AND the
result with
// the processor-specific mask (see "Doodad API v1.6", page 201).
result &= getProcessorMask();
// Set the user field value based on the "Marigold Formula."
// (see "Doodad API v1.6", page 136)
setUserField((result + kMarigoldOffset) / MarigoldConstant + MarigoldConstant);

 
 
이 코드는 구체적인 문맥 없이 발췌한 코드의 일부분임에도 불구하고,
주석은 각 라인이 코드에서 무엇을 의미하는지 잘 알려준다.
주석이 없다면 & 연산자와 "Marigold Formula'가 무엇을 의미하는지 알 수 없을 것이다.
 

NOTE

모든 문장마다 주석을 다는 방식이 바람직하지 않을 때가 많지만,
코드가 굉장히 복잡하고 난해해서 굳이 이 방식을 적용해야 한다면
코드를 그대로 번역하지 말고 앞선 예제처럼 코드의 작성 의도를 설명한다.

 
 

Prefix Comments( 머릿말 주석 )

소스 파일의 첫머리를 항상 표준 주석으로 시작하도록 정하는 방법도 있다.
작성할 프로그램이나 파일 관련 주요 사항을 여기에 남기면 좋다.
이처럼 소스 파일의 첫머리에 남기면 좋은 정보는 다음과 같다.
 

  • 저작권 정보
  • 파일과 클래스에 대한 간략한 설명
  • 최종 수정 일자*
  • 최초 작성자*
  • (앞에서 언급한) 변경 내역*
  • 파일에서 구현한 기능의 ID*
  • 미완성 기능 **
  • 발견된 버그 **

* 항목들은 대부분 소스 코드 관리 시스템이 자동으로 작성해준다.
** 항목들은 버그 및 기능 추적 시스템이 처리해준다.
 
Subversion(SVN)과 같은 일부 소스 제어 시스템은 메타데이터를 채워 넣는 데 도움을 줄 수 있다.
예를 들어, 주석에 $Id$ 문자열이 포함된 경우, SVN은 주석을 자동으로 확장하여
작성자, 파일명, 수정본, 날짜를 포함할 수 있다.
접두 주석의 예는 다음과 같다:

/*
* $Id: Watermelon.cpp,123 2004/03/10 12:52:33 marcg $
*
* Implements the basic functionality of a watermelon. All units
are expressed
* in terms of seeds per cubic centimeter. Watermelon theory is
based on the
* white paper "Algorithms for Watermelon Processing."
*
* The following code is (c) copyright 2017, FruitSoft, Inc. ALL
RIGHTS RESERVED
*/

 
 

Fixed-Format Comments ( 고정 양식 주석 ) 

 
표준 형식으로 주석을 작성하여 외부 문서 생성기가 구문 분석할 수 있도록 하는 것은
점점 각광받고 있는 프로그래밍 관행이다.
자바 언어에서는 프로그래머가 표준 형식으로 주석을 작성하여
JavaDoc이라는 도구가 프로젝트에 대한 하이퍼링크 문서를 자동으로 생성할 수 있다.
C++에서는 www.doxygen.org 에서 제공되는 무료 도구인
Doxygen이 주석을 구문 분석하여
HTML 문서, 클래스 다이어그램, UNIX man 페이지 및 기타 유용한 문서를 자동으로 생성한다.
Doxygen은 C++ 프로그램에서 JavaDoc 스타일의 주석도 인식하고 구문 분석한다.
 
 
이 외에도 임의 주석과 같이 정해진 형식과 관계 없이 필요할 때마다 
주석을 달 때가 있으며, 이런 주석을 작성할 때는 다양한 가이드라인을 따른다.
또한 코드가 곧 문서인 코드가 있다.
잘 작성된 코드는 대체로 주석이 적고 쉽게 이해할 수 있다 (EX. UE 내부코드)
코드가 문서 역할을 하도록 작성하는 또 다른 방법은
코드를 더 작은 단위로 쪼개는 코드 분해라는 것도 있는데,
코드 분해란 코드를 더 작은 단위로 나눠서 작성하는 방식이다.
소스 코드 파일을 열어보느 수백 줄에 달하는 함수로 가득 차 있고 (EX. WinError.h)
수많은 블록이 복잡하게 중첩된 한 가지 작업을 처리하는 데 필요한 일도
복잡하다면 별도의 함수나 메서드로 분해하는 것이다.
 
이외에도 다양한 규칙이 있으니
꼭 책을 읽어보길 바란다.
 

논외이긴 하지만, 필자는
거듭되는 주석 이야기를 통해 "주석까지 코드"라고 느꼈다.
헬스에서 식사와 휴식까지가 운동입니다 라고 하는 경우처럼 말이다.