좋은 프로그래밍 습관 DarkKaiser, 2007년 7월 1일2023년 8월 30일 델마당 – 이민규 님의 글 #1 – 프로그램의 작성순서 – 프로그래머 중 많은 사람들은 코드작성을 바로 시작합니다. 그리고 생각나는데로 변수이름을 정하고 프로그램을 조금씩 짜가며 컴파일 해서 에러가 나는지를 검토하고 다시 짜기 시작합니다. 그러다가 나중에 문제가 발생하면 변수를 하나씩 추가하기도 하고 또는 변수의 이름을 바꾸거나 삭제 합니다. 그러다가 정 않되면 포기해 버립니다. 만약 당신이 위의 습관을 가지고 계신다면 빨리 버리도록 노력하십시오. 필자도 그런 습관을 버리려고 노력을 많이 하고 있습니다. 그 습관은 아주 좋지 못한 것입니다. 그런 습관이 프로그램을 비효율적으로하며 버그발견시 잡아낼 확률은 매우 커집니다. 코드가 길어질수록 프로그래머의 시간과 노력을 빼앗아 갑니다. 이제 제가 프로그래밍의 순서를 나열하여 보겠습니다. 1. 문제정의 여러분이 프로그래밍을 해야하는 이유는 무엇입니까? 도대체 어떤것이 불편하고 또 어떤것이 필요합니까? 2. 요구분석 사용자가 요구하는 사항은 무엇입니까? 사용자가 필요로 하는 기능을 무엇입니까? 혹 사용자가 좀 더 빠른 화면 제어를 원합니까? 3. 구현 계획 당신은 프로그램을 만드는데 걸리는 시간은 어느정도로 생각합니까? 당신을 도와 같이 일할 사람은 누구입니까? 혹 당신이 그래픽을 맡습니까? 또 어떤 언어들을 사용합니까? 4. 기본 설계 (아키텍처 설계) 당신이 만들 프로그램을 크게 대략적으로 설계를 해 보십시오. 그 뼈대를 만드는데 당신은 많은 노력을 들여야 할 것입니다. 과연 어떤 기능들이 있습니까? 또 프로그램은 몇개의 모듈로 나누어 집니까? 3. 세부 설계 프로그램에 사용되는 루틴은 어떠한 것이 있으며 또한 그것들은 재사용성이 충분합니까? 또한 어느정도의 메모리를 소모하며 변수들은 어떤것들이 있습니까? 혹, 당신이 객체지향 프로그래밍을 한다면 당신의 객체들의 속성은 무엇입니까? 그 객체가 이름을 가지고 있습니까? 아니면 총을 가지고 있나요? 4. 코딩과 디버깅 이제 당신은 컴퓨터를 켜고 기본 설계를 염두에 두고 세부 설계를 바탕으로 코딩을 해나가야 할 것입니다. 여기서 주의 할점을 세부사항과 그 이전의 내용를 결코 변경해서는 안됩니다. 그것을 변경함은 그 프로젝트 실패의 지름길 입니다. 그리고 코드 하나 하나에 신경을 쓰십시오 그 다음 강좌부터는 주로 코딩방법에 관하여 글을 쓸 예정입니다. 그리고 컴파일을 한 후 디버깅 작업을 하십시오. 5. 단위 테스트 여러분이 작성한 프로그램의 단위(파스칼에서는 유닛정도…)별로 테스트를 하십시오. 되도록 모든기능을 테스트하고 버그가 있을경우 뼈대에서 빚나가지 않을 정도로 수정하십시오. 6. 시스템 테스트 여러분이 작성한 프로그램을 당신의 컴퓨터가 아닌 다른 컴퓨터에서도 작동하는지를 검사하십시오. 다른 여러가지 이유로 작동이 안될 수도 있으며 만일 작동이 안될경우에는 그 시스템의 조건을 분석하여 자신의 시스템과 비교하여 다른점에서 우선적으로 검사를 하십시오. 7. 유지 관리 당신의 프로그램을 안전한 곳에 보관하며 또한 안전한 관리를 해야 합니다. 또한 업그레이드가 필요하면 적정수준에서 특정기능을 추가 하십시오. 업그레이드하는데 문제가 많이 발생한다면 당신은 ‘기본설계’와 ‘세부설계’에서 잘못되었을 가능성이 크므로 처음부터 업그레이드를 염두에 두고 설계하십시오. 이제 당신의 프로그램이 완성되었습니다! 위의 순서를 잘지키려고 노력하면 분명히 좋을 결실을 얻을 수 있을것입니다. 큰 프로젝트를 수행할 수록 위사항을 더욱 철저히 지켜져야 할 것입니다. 처음에서 작은 프로젝트부터 시작하고 점점 큰 프로젝트에 도전하십시오. 그럼 많은 도움이 되었으면 합니다. 안녕히… #2 – 프로그램의 분할 – 여러분이 만약 프로그램을 만드는데 있어서 분할을 하지 않고 만든다면 매우 힘들것입니다. 프로그램을 가독성(읽고 이해하기 쉬운정도)가 떨어지고 또한 버그의 가능성은 엄청나게 커지는 것입니다. 또한 단위테스트(unit test)가 불가능하지요… 어쨌든 좋은 프로그래밍을 하는데 아주 큰 영향을 미치는 것이 바로 얼마나 프로그램의 분할을 잘했느냐 입니다. 이것에 따라 프로그램의 확장성이 커지느냐 아니면 불가능하느냐가 좌우되며 재사용성의 생명이 여기에 달렸다고 해도 과언은 아닙니다. 프로그램의 분할을 궂이 나누자면 모듈과 루틴으로 나눌수가 있겠습니다. * 루틴은 프로그램의 세세한 분할, 즉 프로시져나 함수등이 바로 이 루틴이라고 할 수 있겠습니다. * 모듈(module)은 흔히 파스칼에서 말하는 바로 유닛(unit)입니다. 모듈은 비슷한 기능을 가진 루틴의 집합이라고나 할까요… 예) graph 모듈 +– ?PutPixel 루틴 +– ?SetColor 루틴 +– ?GetImage 루틴 +– … 그럼 우리는 왜 루틴을 작성해야 하는지 그 이유를 한번 알아봅시다. * 복잡성의 감소 * 코드의 중복을 피함 * 코드 변경시의 영향을 제한함 예) setColor(blue); bar(x, y, x+100, y+100); 만약 위의 코드를 10군데에서 사용했다고 하면,… 당신이 파란색이 맘에 안들어서 빨간색으로 바꾸려고 한다면 모두 10군데의 코드를 찾아서 그 코드를 고쳐야 합니다. 하지만 루틴으로 작성했다면 그 루틴만 고치면 되지요… – 만약 당신이 위와 똑같은 코드를 루틴으로 작성한다면 그 루틴은 좋지 못한 루틴입니다. – * 내용의 은폐 당신이 콜라 자판기에서 콜라를 빼먹는데 필요한 것은 동전넣는 구멍과 선택버튼 뿐입니다. 그 속의 가스주입기나 콜라액기스 주입기 또는 컵 인출기는 알필요도 없을뿐만 아니라 알아봐야 콜라 빼먹는데는 도움이 안됩니다. * 코드의 재사용성 증진 * 판독 가능한 코드의 작성 * 이식성의 개선 * 테스트의 용이함 대충 위의 사항들은 우리가 왜 루틴을 작성해야 하는지에 대한 답을 주고 있습니다. 루틴을 작성함으로써 우리에게 가져다주는 잇점은 너무나 분명하며 또한 그 힘은 매우 막강하다고 할 수 있습니다. – 루틴의 작성법 – 우리가 루틴을 작성하려고 하는데 어떻게 하면 잘 만들었다고 소문이 날까하고 생각하게 됩니다. 다음은 그 해답을 제시하려고 합니다 1. 강한 응집성 우선적으로 루틴은 그 루틴내의 연산들이 강한 응집력을 가지고 있어야 합니다. procedure doing; begin ?MotherName := ‘Sally’; ?SetColor(blue); ?PutImage(xPos, yPos, ?FatherImage, ?NormalPut); … end; 위의 루틴은 곧장 쓰레기 통으로 가야 할것입니다. 응집성이 매우 떨어지며 또한 루틴의 이름도 적정치 못합니다. 당신은 doing 이라는 이름만 보고 그 루틴이 어떠한 작용을 할지를 추측할수 있겠습니까? function getFatherName(fam: family): string; begin getFatherName := fam.Father.Name; end; 위의 루틴은 그 기능이 매우 명확하며 이름만 보고도 무슨기능을 하는지를 바로 알수가 있습니다. 좋은 루틴은 이름과 관계가 깊습니다. 만약 당신이 만든 루틴에 이름이 부여하는데 고심하고 있다면 아마 그 루틴은 잘못작성된 루틴일 가능성이 큽니다. 즉, 기능적 응집력이 떨어질 가능성이 있다는 것이지요… – 응집성의 종류 – (1). 기능적 응집성 어떤 기능에 따라 루틴을 나누고 작성한것. 아주 좋은 루틴! 예) getEmployeeName, sin, ?FileReName,… (2). 순차적 응집성 루틴이 반드시 특정 순서에 의해 작성되어져야 할 때 쓰임 예) ?DoStep1, ?FirstProcess,… (3). 일시적 응집성 동시에 일어나야 하는 연산들에 의한 응집 예) Initialize, ?StartUp, … (4). 기타 그 외의 응집성은 받아들여 지기가 힘들것입니다. 2. 소결합 (Loose Coupling) 이것은 두 개의 루틴간에 연결되어 있는 강도를 말합니다. 루틴간의 좋은 결합은 루틴이 다른 루틴에 의해 쉽게 불려질 수 있도록 느슨하게 해야 합니다. 루틴의 매게변수는 매우 중요한 역할을 합니다. 만약 서로 다른 두 루틴에서 똑같은 전역변수가 쓰여지거나 변경된다면 매우 위험한 루틴입니다. 왜냐하면 감히 그 전역변수의 값을 추측하기가 힘들기 때문입니다. 그 루틴이 호출되어 버리면 바로 그 전역변수의 값은 변하기 때문입니다. 또한 그 루틴이 반복문에 들어있다면… @.@ 루틴의 매게변수를 잘 설정 하십시오. 좋은예) sin(radian), ?FileReName(?OldName, ?NewName), … 나쁜예) ?IncreaseAllCounter, procedure ?SetName(order: integer; ?NewName: string); begin People?order.Name := ?NewName; { People은 전역변수.. } end; -> 좋게 바꾸면… procedure ?SetPeopleName(peo: peopleType; ?NewName: string); begin peo.Name := ?NewName; end; 3. 방어적 프로그램 어떤 루틴에서만 사용하는 변수를 전역변수로 둘 필요는 없습니다. 아니 그런한 행위는 아주 위험할 수 있습니다. 안좋은 예) var sumA, sumB: integer; function sum: integer; begin sum := sumA+sumB; end; -> 좋게 바꾸면 function sum(a, b: integer): integer; begin sum := a+b; end; 이제 까지 우리는 루틴의 작성법에 대한 아주 기본적인 것만을 알아 봤습니다. 위의 예들은 매우 극단적인 것이며, 아마 위의 나쁜예 처럼 사용하는 유저는 아마 드물것입니다. 하지만 그 것은 확장 응용 시켜 당신의 프로그램에서 실수를 하지 않도록 하는것은 여러분의 몫입니다. 그럼 다음 강좌에서 뵙도록 하지요…이만.. #3 – 주 석 문 (Comment, Remark) – 우리는 보통 프로그래밍 하는데 주석문을 중요시하지 않는 경향이 있는것 같습니다. 사실 주석문이 프로젝트의 성공률에 크게 영향을 미친다면 여러분은 믿으시겠습니까? 주석문은 그 프로그램을 설명하는 기능을 가진다는 것은 누구나 잘 알고 있는 사실입니다만, 과연 어떻게 설명을 해야 하는지, 또 어떤형태로 쓰여져야 하는지에 대해서는 잘 모르고 계신분들이 많습니다. 그건 사실입니다. 시중에는 그러한 것을 설명해주는 책 같은것은 찾아보기가 힘듭니다. 그 또한 제가 이 글을 쓰게된 동기중에 하나이지요…이 글에서는 주석문에 대한 추상적인 설명보다는 주석문을 다는 한가지 방법을 소개 하고자 합니다. 오히려 그것이 더 실용적일 수 있으며 또한 그것을 바탕으로 더 발전해 나갈 수 있으리라고 생각합니다. – PDL (Programming Design Language) – PDL 은 주석문을 달기위한 방법이 아닙니다. 단지 PDL 그 차체가 주석문이 될 수 있습니다. PDL 은 케인, 파버, 고든사에 의해 개발되었으며 1975년에 발표되어 지금까지 발전을 거듭해 왔습니다. 대부분의 프로그래머들은 플로우 챠트(Flow Chart)를 사용하지 않습니다. 아니 매우 드물죠. 왜냐하면 플로우 챠트는 그리기가 매우 귀찮고 또한 큰 프로그램을 만들경우 그 작업이란 보통 큰 작업이 아니죠… 그래서 많은 프로그래머들은 바로 이 PDL 을 사용합니다. PDL 로 프로그램을 디자인 해 놓으면 그 것을 그대로 주석문 대신 사용할 수가 있기 때문이죠… *** PDL 의 특징 및 준수사항 *** 1. 특정 연산을 정확히 기술하는데 영어적인 포현을 사용한다. 2. 특정 언어의 표현을 사용하지 않는다. (불필요한 문법적 규칙에 얽매여서는 않된다.) 3. 의도하는 수준의 PDL 을 쓴다. 접근이 의도하는 언어로 어떻게 구현되는지 접근의 의미를 기술한다. 4. PDL 을 단지 코드로 옮겨 쓰기만 하면 될 정도로 자세하게 기술해야 한다. 나쁜 예) Open file assign(f, Filename); reading datas if data=Empty then Close(f) else read all datas close(f); 위의 예의 문제점은 바로 특정 언어의 표현이 들어갔다는 점이다. close(f) 라든지 assign(…) 등은 파스칼이라는 특정언어의 표현이 들어갔다는 것이다. 특히 어떤 연산 표현등은 조심해서 피해야 한다. :=, <>, ++, =+ .. 등… 좋은 예) open the file if file data is empty write the file is empty and call ERROR else reading all data and write the BUFFER array close the file 위와 같이 특정 언어의 표현을 피하고 그 자체로써 어떤 프로그램인지 이해가 가능한다. 또 충분히 자세한 표현을 해야한다. 우선 그렇게 만들어 두면 주석문으로 바꿔서 코드를 달기가 쉬워진다. 워의 예에다가 코드를 붙인것) { open the file } Assign(f, ?FileName); Reset(f, 1); { if file data is empty } if ?FileSize(f)=0 then begin { write the file is empty and call ERROR } Writeln(‘This File is Empty- Error!’); ?ErrorCode(?ErrFileEmpty); end { reading all data and write the BUFFER array } else begin ?BlockRead(f, BUFFER, ?SizeOf(BUFFER)); end; { close the file } Close(f); 이렇게 하면 완성입니다.!… 그런데 아마도 이런생각을 하는 분이 계실지도 모르겠군요. ” 이건 영어를 잘해야 하쟎아! 난 영어를 못 하는데…쩝 실망…” 걱정할 필요없습니다. *** 한글이 있지 않습니까 *** 위의 사항만 지키되 한글로 쓰면 그만 입니다. 그럼 한국인을 누구나 PDL 을 사용할 수가 있을 것입니다. 그럼 다음 강좌에 뵙죠… 그럼 이만…. #4 – 이름 붙이기 – 이름을 붙인다는 것은 매우 힘들고 까다로운 일이다. 적어도 이름을 붙이는데 고심을 해 보지 않은 사람은 아무도 없으리라 생각한다. 이름을 잘만 붙이면 스스로 설명하는 코드가 되므로 코드의 유용성과 가독성이 매우 커진다… 0. 대소문자의 구분 파스칼에서는 대소문자의 구분이 없다. 한마디로 FILENAME, ?FileName, fileName 등… 모두 같은 식별자로 취급한다. 그 장점이 있는 반면 단점도 있다. C 에서는 대소문자를 구분한다. 또한 파스칼의 제작자인 Niklaus Wirth 가 차후에 만든 언어인 OBERON 에서도 대소문자를 확연히 구분한다. New, new 는 다른것이다. 장점은 역시 버그의 가능성을 줄여준다. 만약 ?FileName 이란 단어를 뒤에서 실수로 Filename 이라고 치더라도 컴파일러는 상관하지 않는다. 허나 C, OBERON 에서는 즉시 에러를 발생한다. 혹 프로그래머가 그 차이를 인식하지 못한다면 그 에러를 잡는데 꽤나 고생할 것이다. “분명히 ?FileName 이라고 쳤는데 왜 에러가 날까?” 하며 화를 낼지도 모른다. 그것은 코드가 길어질 수록 힘들다. 단점은 소스코드가 지저분해질 가능성이 역력히 있다. 위에서는 ?FileName 이라고 썼다가 밑에서는 filename이라고 썼다가… 또 하나의 단점은 그 만큼 식별자의 표현 방법 수가 줄어든다. New 와 new 를 같은 것으로 취급하므로 다른언어에서는 NEW 에서만도 NEW, ?NEw, ?NeW, New, nEW, nEw, neW, new 이미 8가지의 표현 가지수를 제공해 준다. 하지만 위에서와 같이 쓸일은 아마 드물것이다…. * 보통 파스칼에서는 의미 단위로 그 첫자를 대문자로 쓴다. 예) ?FileName, New, ?GetImage, ?DeleteFile, ?PrintReport, … 1. 변수 이름 붙이기 변수 이름을 붙이는데 신경을 전혀쓰지 않는사람들이 종종 있다. 그것은 좋지 못한 습관이며 빨리 개선하려고 노력해야 할 것이다. 나쁜예) var i, j: integer; a, b, c: word; n, q, r: string; … 위의 예는 종종사용하는 변수명이며 아주 일반화 되어 있는것 같다. 그러나 단 하나의 변수명이라도 신경쓰지 않으면 안된다. 특히 전역변수명은 충분히 역할이 인식되어질 수 있도록 잘 붙여야한다. 좋은 예) var ?CurrentDirectory: string; ?TotalFileNumber: integer; Index: integer; … 위와 같이 변수명만 보고도 어떤 역할을 할지 충분히 짐작할 수 있어야 한다. 단 서브루틴의 경우에서는 그것을 조금은 허용할 수가 있다. 서브루틴에서 단지 잠깐 저장하기 위한 변수 이름들은 단순할 수가 있다. 예) function Factorial(n: integer): integer; begin if n=0 then Factorial := 1 else Factorial := Factorial(n-1)*n; end; 위의 루틴은 단순히 한 숫자를 입력 받는것이므로 n 이라고 표현해도 무방하다. 복잡한 이름은 오히려 프로그램의 복잡성을 가중시킬 수 있다. 2. 루틴의 이름 (1) 프로시져 이름 프로시져의 이름은 가장 좋고 일반적인 것은 *** 동사+목적어 *** 이다. 좋은 예) ?DeleteFile, ?ChangeDir, ?PrintReport, ?ClearScreen …. 위의 형태는 모두 동사+목적어의 형태로써 그 의미가 매우 명확하다. (2) 함수의 이름 함수의 이름은 복귀값에 대한 설명이 충분해야 한다. 좋은 예) ?GetCurrentColor, ?PrinterReady, ?ErrorMessage, … 위의 형태는 모두 복귀되는 값이 어떤 값인지 충분히 짐작할 수 있다. 3. 접두사 접두사와 접미사를 사용하는것은 의미를 명확하게 하고 또한 프로그램의 일관성을 부여할 수 있다. 접두사의 예) ?PutImage, ?SetColor, ?GetCurrenFileName, …. 접두사는 주로 사용되는 것이 Put, Get, Set, …. 등이 있다. 프로젝트를 수행할 때는 접두사의 규칙을 정하는 것이 원칙이다. 4. 기 타 * 의미가 어렵거나 분명하지 않은 단어는 사용을 되도록 피하도록 한다. 예) ?HandleCalculation, ?ProcessData, … * 루틴이 하는 일을 모두 설명할 수 있어야 한다. 루틴 이름과 관련없는 연산들은 그 루틴에 포함되어서는 안된다. * 루틴명의 길이는 최적의 평균 길이는 9~15 자 이다. 그러나 평균적으로 현실적인 이름은 15~20자가 적당하다. 루틴의 이름은 프로그램의 크기에 따라 길어질수도 짧아질수도 있다. * 이름 짓기를 위한 규칙을 제정 특히 여러사람이 프로그래밍 프로젝트에 참가할 경우 모여서 이름 짓기에 관한 규칙을 제정해야 한다. 그럼으로써 프로그램이 더 표준화 되고 일관성이 생긴다. 예) Get 의 접두사를 붙이면 버퍼의 내용을 삭제하면서 그 내용을 가져온다. Query 의 접두사를 붙이면 버퍼는 그대로 있고 그 내용을 가져온다. 이상으로 이름 짓기에 관한 아주 기초적인 내용을 알아보았습니다. 여러분의 프로그램과 언어공부는 잘되어 가고 있는지 궁금하군요… 그럼 앞으로도 열심히 하시고, 프로젝트 성공하시길 빕니다. 그럼 이만… #5 – 배치와 스타일 – * 필자의 파스칼 배치와 스타일 * procedure ?DecToHex(d: integer); const ?HexStr: string = ‘0123456789ABCDEF’; begin if d<16 then write(?HexStr?d+1) else begin ?DecToHex(d div 16); write(?HexStr?(d mod 16)+1); end; end; 위 프로시져는 10진수를 16진수로 출력해주는 프로시져 이다. 위의 배치와 스타일을 잘 분석해보면 예약어(key words) 들은 모두 소문자로 썼슴을 알 수 있다. 또한 사용자가 정의한 변수나 루틴명은 모두 의미별로 첫단어의 첫글자는 대문자로 썼다. 또한 단락별로 2개의 공백을 두었으며 begin 은 올려썼다. begin 과 end 의 위치에 관해 두가지 입장을 가진 프로그래머들이 있다. 한 가지는 begin 은 그 위의 문장의 뒤에 이어져야 한다. 예) for i := 1 to 100 do begin … end; 다른 한 가지는 begin 은 새로운 줄에 입력되어 end 와 그 위치를 맞추어애 한다. 예) for i := 1 to 100 do begin … end; 두 가지 모두 일리가 있으며 여러분은 그 중 하나를 택하면 된다. 필자는 위의 논리를 따르고 있으며 실제로 파스칼을 만든 Niklaus Wirth 가 후에 만든 언어 OBERON 에서는 다음과 같이 되어있다. FOR i:=1 TO 100 DO … END; IF a=b THEN … ELSE … END 여기서는 아예 begin~end 의 논리를 깨고 단지 END 만을 중요시 여겼다. 키워드를 이 BEGIN 의 의미를 가지고 있다고 본다. 위의 OBERON 스타일이 필자가 보기에는 가장 쉽고 깔끔한 프로그래밍을 도와준다고 생각한다. * 필자가 제시하고 권장하는 배치와 스타일 * 이것은 단지 필자의 습관일 뿐 여러분 자신의 배치와 스타일이 있다면 애써 바꿀 필요는 없다. 허나 그 습관이 나쁜 습관이라면 빨리 고치도록 노력하는 것이 좋을 것이다. 괄호 안에 있는것은 필자의 스타일이다. 1. 대,소문자의 일관성을 유지한다. (1) 예약어(key words) 들은 일관성 있는 스타일을 가진다. (모두 소문자) (2) 사용자 정의 인식자들은 (의미별 단어마다 첫 글자에 대문자를 쓴다.) 2. 들여쓰기 (1) 단락별로 (2 공백)의 차이를 둔다. (2) begin 예약어의 위치는 (해당 키워드의 가장 뒷 부분에 쓴다.) (3) 다음과 같은 불규칙한 들여쓰기는 피한다. if a=b then a:=a+1 else begin b:=b+1; for i:=1 to 100 do begin write(i); … end; * 문제점 위의 코드는 들여쓰기의 일관성이 없다. 단지 바로 윗 줄의 단어에 신경을 썼을뿐이다. 위와 같은 코드는 지저분해지기 일쑤다. # 위의 코드를 바로 고친 코드 # if a=b then a := a+1 else b := b+1; for i := 1 to 100 do begin write(i); … end; 3. 주석문의 위치 주석문의 위치는 해당 라인의 뒤에 가거나 그 라인의 바로 윗부분에 있는것이 좋다. 주석문에 들여쓰기 위치에 맞추도록 한다. 예) { 파일을 지우는 프로시져 } procedure ?DeleteFile(name: string); begin Search(name); { 해당 파일이 존재하는지를 검사한다. } if ?SearchErr<>0 then { 해당 파일이 존재 하면 } … … end; { ?DeleteFile } 위에서 좋은 습관중 하나는 end 뒤에 무엇에 관한 end 인지를 주석문을 이용해서 표시해 주는 것이다. 그렇게 하면 가독성이 좀더 높아 진다. 실제로 OBERON 에서는 다음과 같이 한다. PROCEDURE ?DeleteFile(name: STRING); BEGIN … END ?DeleteFile; 이상으로 대강의 배치와 스타일에 대하여 알아 보았습니다. 그런데 독자적이고 충분이 좋은 습관의 배치와 스타일이 있다면 애써 바꿀 필요는 없습니다. 단지 프로그래밍을 시작하는 단계에 있는 사람들에게 어떤 것이 좋은 습관 인지가 참고가 되었으면 하는 마음입니다. #6 – 기 타 – 여기서는 여러분들이 프로그래밍 함에 있어서 주의해야 할 사항과 팁이 될만한 내용들을 소개하고자 합니다. 1. 재귀호출 (recursion) 재귀 호출이한 그 자신의 루틴을 그 루틴안에서 호출하는 것입니다. 예) 지난번에도 나온 Factorial 함수 function Factotial(n: integer); begin if n=0 then Factorial := 1 else Factorial := Factorial(n-1)*n; { 여기서 자신의 루틴을 호출하였습니다. } end; ————– { 밑줄 친 부분 } 5! = 5x4x3x2x1 * 5 팩토리얼 10! = 10x9x8x…x3x2x1 * 10 팩토리얼 10! = 10×9! 10! = 10x9x8! 위의 알고리즘 아주 단순한 것이므로 스스로 한번 연구해 보시기 바랍니다. 2. 유닛(unit) 을 만들 때의 주의사항 (1) 유닛을 만들 때 가장 주의해야 할 사항은 Interface 와 Implementation 의 구분 입니다. 여러분도 잘 아시다시피 Interface 는 외부로의 공유가 가능하나 Implementation 은 그 내부에서만 사용이 가능합니다. 따라서 유닛을 만들 때 어떤것이 Interface 로 나가야 할지를 주의 하십시오… 내부적인 처리를 하는데 필요한 루틴이나 변수는 Interface 부에서 절대로 선언을 해서는 않됩니다. 그것은 매우 위험한 프로그래밍 입니다. 정보은폐의 원리는 매우 중요하며 이미 저번 강좌에서 콜라 자판기를 예로 설명한바 있습니다. (2) 또한 강한 응집성을 가지도록 설계 합니다. Mytools, ?EtcProc, …. 이와같은 유닛들은 모두 각기의 기능을 가진 루틴의 집합임을 알 수 있습니다. 이것이 매우 좋지 못한 습관이며 다음과 같이 명백하고 강한 응집성을 가지도록 설계해야 합니다. Palette, Color, Graphic, Sound, Music, Font, …. 강한 응집성은 그 유닛이 한가지의 기능에 관련된 것일수록 높습니다. – 강좌를 마치며 – “좋은 프로그래밍 습관을 기르자”라는 강좌가 과연 여러분에게 도움이 되었는지요. 너무 내용이 미흡해서 조금은 걱정이 되는군요… 앞으로 언어 공부 열심히 하시고 프로젝트 성공하시길 바라겠습니다. 프로그래밍 갤러리