////
Search
Duplicate
🏒

9. 의사코드 프로그래밍 프로세스

이 장은 매우 중요한 과정인 클래스와 메소드를 작성하는 과정을 매우 구체적으로 설명하고 있다.
설계와 문서 작성 시 해야하는 작업을 줄여주고 품질을 향샹시키는 의사코드 프로그래밍 프로세스(PPP)에 대해서 설명한다.

1. 클래스 및 메소드 개발 단계 요약

클래스는 다양한 방법으로 구현할 수 있지만 보통은 클래스를 일반적인 형태로 설계하고 클래스 내의 구체적인 메소드를 열거, 구현, 검증하는 과정을 반복한다.

클래스 생성 단계

클래스에 대한 일반적인 설계를 작성한다.
클래스의 구체적인 책임을 정의하고 클래스가 숨겨야할 정보를 무엇인지 정의한다.
클래스 내에 각 메소드를 구현한다.
클래스의 주요 메소드를 식별했다면 각 메소드를 구현해야 한다.
이 과정에서 추가로 다른 메소드가 필요하다는 것을 알게 되며 그러한 추가적인 메소드를 작성하면서 생기는 문제가 전체적인 클래스에 영향을 끼치기도 한다.
클래스를 전체적으로 검토하고 테스트한다.
클래스의 개별적인 메소드 수준에서 각 기능들을 테스트한다.

메소드를 작성하는 단계

메소드에는 접근자 메소드, 다른 객체의 메소드에 대한 직접 호출 메소드 등이 있으며 설계, 설계 검사, 코드 작성, 코드 점검의 과정을 거쳐 작성된다.

2. 전문가를 위한 의사코드

의사코드란 알고리즘이나 메소드, 클래스, 프로그램이 어떻게 동작할지를 기술하는 표기법을 가리킨다.
의사코드는 자연어와 비슷해서 생각을 정리하기 위해 충분한 설명이 가능하다. 다음은 의사코드를 사용하는 특히나 더 유용한 방법들이다.
구체적인 연산을 정확하게 기술하기 위해 자연어 문장과 같은 형태의 명령문을 사용한다.
특정 프로그래밍 언어의 요소를 피한다. 의사코드는 추상화 수준이 더 높은 설계가 가능하다.

3. PPP를 이용한 메소드 구현

메소드를 설계한다

먼저, 선행 조건을 검사한다. 메소드 자체에 대한 작업을 수행하기 전에 메소드가 해야 할 일이 잘 정의되었고 클래스에 어울리는지 검사한다.
메소드가 해결할 문제를 정의한다. 메소드가 해결할 문제를 당장 해결할 수 있을 정도로 자세히 기술한다.
메소드의 좋은 이름을 짓는다.
메소드를 어떻게 테스트할 것인지 결정한다.
표준 라이브러리에서 가져다 쓸만한 기능이 있는지 조사한다.
오류 처리에 대해서 생각한다.
효율성에 대해서 생각한다.
메소드가 자원과 속도의 목표를 달성할 수 있도록 설계한다.
알고리즘과 데이터형을 조사한다.
의사코드를 작성한다.
데이터에 대해 생각한다.
의사코드를 검사한다.
의사코드 상태에서 여러 변형을 시도해보고 가장 좋은 방법을 선택한다.

메소드를 구현한다

메소드의 선언부를 작성한다.
의사코드를 자연어 주석으로 변환한다.
각 주석 아래에 코드를 채운다.
각 코드 블록은 주석에 담긴 생각을 완전하게 구현해야 한다. 각 주석은 일반적으로 2줄에서 10줄 정도의 코드로 확장된다.
코드를 더 나눠야 하는지 검사한다.
주석 아래에 있는 코드가 10줄 이상의 거대한 코드 블록일 경우, 나눠야하는지 확인한다. 이때 다음 두가지 과정중 하나를 고려하라.
주석 아래에 있는 코드를 새로운 메소드로 나눈다. 의사 코드 한 줄이 예상했던 것보다 많은 코드로 확장되었다면 해당 코드를 별도의 메소드로 나눌 수 있다.
PPP를 재귀적으로 적용한다. 의사코드 한 줄 아래에 20줄이 넘는 코드를 작성하는 대신, 원래 있던 의사코드를 여러 줄의 의사코드로 분해한다.

코드를 검사한다

메소드를 설계하고 구현한 후, 세 번째로 해야할 일은 구현한 코드가 정확한지 확인하기 위해 코드 검사를 하는 것이다.
이 단계에서 놓친 오류는 나중에 테스트할 때까지 발견되지 않기 때문에 최대한 이 단계에서 오류를 찾아낼 수 있도록 해야한다.
머릿속에서 메소드의 오류를 검사한다.
코드를 이해하려고 노력해야 한다. 보통 오류는 코드에 존재한다.
작동하는 메소드만으로는 충분하지 않다. 왜 작동하는지를 모른다면 알 때까지 이해하려고 시도해야 한다.
메소드를 컴파일한다.
코드를 디버거에서 한 단계씩 살펴본다.
코드를 테스트한다.
메소드를 개발할 때, 계획했거나 작성했던 테스트 케이스를 사용해 코드를 테스트한다.
메소드에 있는 오류를 제거한다.
오류가 발견되었다면 오류를 제거해야 한다. 이 시점에 개발 중인 메소드에 버그가 많다면 앞으로도 버그가 많을 가능성이 높다.
메소드에 버그가 많다면 처음부터 다시 작성한다.

나머지를 정리한다

코드 점검이 끝났다면 일반적인 특성들을 검사한다. 메소드의 품질이 자신의 기준에 적합한지 확인하기 위해 여러 단계로 이뤄진 정리 작업을 수행할 수 있다.
메소드의 인터페이스를 검사한다. 모든 입력과 출력 데이터를 확인하고 모든 매개변수가 사용되었는지 확인한다.
일반적인 설계 품질을 검사한다. 메소드가 하나의 책임만 가지며 그 책임을 잘 처리하는지 확인하고 다른 협력자들과 느슨하게 결합되어 있는지 확인한다.
메소드의 변수를 검사한다. 부정확한 변수 이름이나 사용되지 않은 매개변수, 선언되지 않은 변수, 부적절하게 초기화된 객체 등을 검사한다.
메소드의 명령문과 논리적인 구조를 검사한다. 무한 루프나 적절하지 않은 중첩, 자원 누수 등을 검사한다.
메소드의 레이아웃을 검사한다. 메소드와 표현식, 매개변수 목록의 논리적인 구조가 명확하도록 공백을 사용해 구분했는지 확인한다.
메소드의 문서화를 검사한다. 주석에서 변환된 의사코드가 정확한지 확인한다. 알고리즘 설명, 인터페이스와 불명확한 의존성에 대한 문서 등에 대한 정당성을 검사한다.
불필요한 주석을 제거한다.

필요한 만큼 반복한다

메소드의 품질이 좋지 않다면 의사코드 단계로 돌아간다. 좋은 프로그래밍은 반복적인 프로세스이니 주저하지 말고 돌아가자.

4. PPP 대안

여기서는 PPP의 몇몇 대안이 되는 방법들을 설명한다.
테스트 주도 개발
테스트 주도 개발은 코드를 작성하기 전에 테스트 케이스를 작성하는 유명한 개발 방법이다.
리팩토링
리팩토링은 논리적인 구조를 유지하며 변경하는 과정을 통해서 코드를 향상하는 개발 방법이다.
개발자는 나쁜 코드의 패턴을 사용하거나 개선할 필요가 있는 코드 영역을 코드 스멜로 정의한다.
계약에 의한 설계
이는 각 메소드가 선행 조건과 후행 조건을 갖고 이싸독 생각하는 개발 방법ㅇ디ㅏ.

요점 정리

클래스와 메소드의 구현은 반복적인 경향이 있다. 특정한 메소드를 구현하면서 얻는 내용이 클래스의 설계에 영향을 끼칠 수 있다.
훌륭한 의사코드를 작성하기 위해서는 이해할 수 있는 자연어를 사용하고 특정 프로그래밍 언어에 특화된 기능을 사용하지 않고 자연어 수준에서 설명해야 한다.
의사코드 프로그래밍 프로세스는 상셰 설계에 유용한 도구이며 코드 작성을 쉽게 해준다. 의사코드는 곧바로 주석으로 변환되며 이렇게 변환된 주석은 정확하고 유용하다.
첫 설계가 완벽한 설계가 아니다. 반복적으로 설계를 개선해나가자.
각 단계에서 작업 내용을 검사하고 다른 사람도 검사하게 한다. 그렇게하면 가장 적은 노력을 들여 실수를 바로 잡을 것이다.