본문 바로가기

일상/좋은글

필드명 및 코딩에 관한 규약

<예전부터 작성해서, 파견업체 마다 돌리던 건데, 시간이 없어 편집하지 못한채, 파일네이밍에 관한 부분만 추가해서 올려 봅니다.

우선 읽어보시고 의견 주시면 다시 반영해서, 정리해 보도록 하겠습니다.

가비웹 식구분들의 의견이 모두 반영되어, 새로운 에이전시에 걸맞는 걸출한 컨벤션이 탄생되기를 기대해 봅니다.

===================================================================

- 본 문서는 codemania와 함께 작업하게 될 여러분들을 위해, 간단한 coding convention을 작성한 것입니다. :-)
- 강제가 아닌(제게 그럴 능력도 없다고 봅니다.) 제안이오니, 확인 후, 함께 convention을 확정 지었으면 합니다.
- 한가지 아울러, 본인은 java를 지나치게 사랑합니다. :-)
(즉, 무조건 java의 기준에 맞추는 습관이 있으니, 이것 역시 옳지 않은 부분이 있다면 조언 바랍니다. 하기사 제가 주로 파견나가는 곳이면, 자바동호회 분위기와 다름 없겠지만. (_-_) )

작은 차이가 명품을 만듭니다. (P업체의 카피라잇 입니다.)

지금 이 글을 읽고있는 저나, 여러분의 실력은 나날이 발전해 가고 있습니다.

현재의 실력이 미천할지라도, 기본적인 컨벤션만 지켜, 프로그램을 개발해 나간다면, 우리의 실력이 증진된만큼, 프로그램의 질을 개선할 수 있겠지만, 마구 짜여진 코드는 질의 개선은 커녕, 재활용성 가능성이 낮아지고, 그렇다면, 우린 허구한날 반복적인 코드를 다시 재작성 해야 합니다.

엉뚱한 소리로 들리겠지만, 본인의 실력을 급진적으로 발전시키고, 그 발전된 실력을 이용하여, 보다 수준높은 프로젝트를 진행하고 싶다면, 컨벤션을 마스터 하십시요. (대충 봐서 될 문제가 아닙니다.)

또한, 소스내 90%의 주석은 컨벤션만으로 제거될 수 있습니다. (주석으로 뒤범벅된 소스는 결코 좋은 소스가 아닙니다. 우리가 오픈소스를 개발하지 않는 이상 말이죠. 또한 설령 오픈소스일지라 하더라도, 개발자용 문서를 별도로 제공하는 것이 옳은 방향이지, 주석을 뒤범벅된 코드는 비정상적 입니다. - 놀랍게도 날고 긴다는? 유명한 오픈소스 개발자 중, 이런 스타일을 고집하는 이들이 많지요. ^^ - )

무작정 주석을 많이 다는게 좋다고 생각하시는 분들이 놀라울 정도로 많은데, 결코 그릇된 생각입니다.
(과중한 주석은 오히려 소스를 가리는 쓰레기의 역활을 합니다.)

주석이 지나치게 많다면, 본인의 코딩스타일과 메서드&함수내 로직, 설계를 점검해 보시기 바랍니다. (대부분 적절한 indirection을 통해서 해결하실 수 있을겁니다. 컨벤션 문서가 끝나는데로, Refactoring에 대해서도 한번 떠들어 보도록 하죠. 자세한 해결법은 그때 이야기 하도록 하겠습니다.)

주석은 반드시 필요한 곳에만, 컨벤션은 반드시 마스터를!


1. 우선 절대적으로 제안하고 싶습니다.

* 잘 알려진 단어외에는 생략하지 마라!

너무나도 많은 사람들이 네이밍시 단어를 생략(예 : image -> img)하는데, 이건 옳지 않은 습관입니다.

생략된 단어가 표준과 다른 없는 경우(HTML, UML, URL, DB)를 제외하고는 절대! 생략하지 마십시요.

제발 부탁 드립니다. 정말 중요한 부분입니다.

* 한글발음식 네이밍, 콩글리쉬는 제발 no!

jumunCode(주문코드) -> orderCode (변수, db field 네이밍의 경우)
getFinishTaskList() -> getFinishedTaskList() (method, function의 경우)

* indentation의 간격은 현 추세에 맞추어!

의외로 2, 8등으로 셋팅하고 쓰시는 분들이 많습니다만, 4가 적당해 보입니다. (표준은 8이 맞죠)

스페이스를 삽입하는냐, 탭을 쓰느냐는 전적으로 본인의 판단에 맞추겠습니다.


* 단일 라인은 80을 넘지 않도록. (시대에 따라, 이젠 옵션사항이 되어 버렸습니다. ^^)

terminal, 낮은 해상도의 사용자, 소스출력등을 위해, 단일 라인이 80을 넘지 않도록 해주시기 바랍니다.

사실 여기에 대한, 진부한 논쟁이 없는것은 아니지만, 미천한 경험이나마, 본인의 경험상 나쁠 것 없더군요.

그래도 위의 단점들을 커버할 수 있는 도구들이 나와 있으니, 반드시 지키지 않아도 될 것 같습니다.
(그러나 터미널 작업이 주인 아파치등의 소스는 차치하고서라도, Delphi등의 IDE에서는 거의 강제적으로 제한하고
있는 추세입니다. 그러나 본인도 사실 지키지 않고 있습니다. 해상도가 아까워서요.)

* 영문자 외에는 네이밍에서 제외

상수를 제외한, 클래스&인터페이스, 메서드&함수, 변수 네이밍시 영문자들 제외한 일체의 문자는 제외시켜 주십시요.

예 : (_, -등과 같은 특수문자들)

상수는 예외적으로 _ 문자를 인정합니다만, 단어구분자로써만 사용하셔야 합니다.

물론 언어마다의 컨벤션은 모두 다릅니다.

그러나 팀작업이란 점을 감안하면, 한가지 컨벤션으로 통일하는 것이 좋겠지요.


* 변수 선언

형타입이 동일하고, 주석에 대한 별도의 주석이 필요없다면(대부분 네이밍으로 해결할 수 있지요.), 한 라인에 여러 변수를 선언하여도 됩니다.

다만, 형타입이 다른 변수를 한 라인에서 선언하지 마십시요. (형타입이 다르다면, 무조건 다른 라인에!)

또한 변수의 데이터타입고 변수명 선언시 1 space를 삽입하는 것이 일반적이나, 탭을 삽입하는 것도 허용합니다.
(여러 데이터타입이 섞여있어 가독성이 떨어지는 경우 사용하면 유용합니다.)

예 :

int age;
int serial;
Object sample;

또는

int age;
int serial;
Object sample;


가장 중요한 거!

변수는 해당 변수가 사용되는 블럭(class, method, if, while...)의 최상단에 모두 선언하십시요.

결코! 절대! never! 그 변수가 사용되는 위치에서 선언하지 마십시요. 이렇게 까지 강조했는데 이해 하셨죠?)

php와 같은 특정 language 에서는, while 문 내에서 생성된 변수도, 해당 루프가 소멸되어도 유효합니다.

설령 그렇다 할지언정, 위의 규칙은 불변합니다.


* 변수초기화

지역변수의 경우는 선언시 반드시 초기화를 해주세요. (기본적인 사항이니 강조할 것도 없지요?)

예 : int count = 0;

오직, 단 한가지 이유, 초기화 되지 않은 변수를 가지고 연산시 끔찍한 일이 벌어지기 때문입니다.
(php, perl과 같은 자유로운 형변환을 허용하는 언어 일지라도 지켜 주십시요.)


* 파라미터의 값은 변경하지 말아주세요!

대부분의 분들이 아무런 생각없이 parameter로 넘어온 변수의 값을 재할당 하는 경우가 많습니다.

파라미터 변수의 값은 기본적으로 final로 고정하여 주십시요. (이건 정말 큰 재앙입니다.)

파라미터 변수의 값을 변화하고자 한다면, 새로운 변수를 선언한 후 사용하시기 바랍니다.

예 : 아래의 메서드는 이름을 입력받아, "greate" 붙인 후 리턴하는 메서드 라고 가정해 봅시다.

getUserName(String name) {

name = "greate " + name; // 파라미터 변수의 값을 건들지 말란 말이야!

return name;

}

요거는,

getUserName(String name) {

String addedName = null;

addedName = "greate " + name;

return addedName;

}

* 리턴문에서 가급적 연산, 괄호, 메서드 호출은 자제하고, 반드시 특정값을 리턴합시다.

나쁜예 :

return;
return 특정객체.특정메서드();
return (size ? size:defaultSize);


* 각각의 메서드는 빈줄로 구분합니다. (너무나 당연)

요런식으로, 새로운 변수를 선언해 사용하시면 됩니다.

1. 패키지 네이밍

모든 패키지는 반드시 소문자로만 네이밍 해야합니다. (복수단어 동일)

또한, 모든 패키지명의 시작은 현재의 도메인, 또는 국가를 구별할 수 있는 두자리 영문코드로 시작해야 합니다. (1981년 ISO 표준 - 3166)

예 : com.codemania.extend.tool;

패키지 하부 컴포넌트의 네이밍은 편하신 방식으로 마음껏 정하셔도 상관없습니다.

예 : 부서별, 프로젝트별, 머신별, 로그인 네임별등

2. 클래스, 인터페이스 네이밍

무엇보다, 심플하고, 자신을 스스로 잘 설명할 수 있는 이름으로 지어주어야 합니다.

또한, 각각의 단어의 첫번째 철자는 모두 대문자로 시작한다는 건, 너무 잘 알려진 사실이죠.

예 : PaymentManager, LogTracer)


3. 메서드, 함수 네이밍

반드시 행위를 표현하는 동사로 시작하십시요.

또한, 모든 메서드&함수 네이밍은 소문자로 시작하고, 여러 단어가 섞여있는 경우, 첫 단어(소문자)를 제외한 나머지 단어는 첫 문자를 대문자로 시작하도록 합니다.

예 : getUserList (동사가 가장 앞에 위치, User, List는 첫 문자가 대문자로 시작)

잘못된 네이밍 예 : getUserlist(userlist란 단어는 세상에 존재하지 않습니다. user와 list는 엄연히 다른 단어죠)

또는 종종 이렇게 하시는 분들도 있더군요.

getBackGroundImage(X) -> getBackgroundImage(O)

background는 한단어가 맞습니다. (이 경우는 영어공부가 우선이겠죠. 사실은 본인의 경험담 이랍니다. ^^)

단, 생략된 단어의 경우, 모두 대문자로 네이밍 하셔야 됩니다.

예 : getDBConnector

잘못된 네이밍 예 : getDbConnector(이외로 이렇게 하시는 분들이 많습니다만, 생략된 단어는 기본적으로 모두 대문자로 기입하십시요. 절대 중요한 부분입니다.)

3. 변수 네이밍

변수명은 _(underscore), $로 시작하지 마십시요. (라곤 하지만, 사실 본인도 member 변수에 한정해, underscore로 시작하는 네이밍을 고집하고 있습니다. 아~ 혼란이 오는군요. 이건 한번쯤 미팅을 가져 보도록 하지요.)

첫 단어는 모두 소문자로, 이어지는 단어는 첫문자만 대문자로, 생략어는 모두 대문자로. (메서드&함수와 같지요.)

변수명은 가급적 간결하게, 그러나 의미는 충분히 내포하게끔! (말은 쉽다!)

단, i, j, k, m, n(정수형), c, d, e(문자형)을 위한 변수사용은, 루프내에서는 허용합니다.


4. 상수네이밍

상수는 좀 특별합니다.

모든 단어는 대문자로, 각 단어는 _(underscore)로 구분하셔야 합니다.


기타...


5. 주석

주석의 경우는, 여러 문장의 주석이 있을 경우는 아래와 같은 식으로...

/**
*
*
*/

단일 주석의 경우는 //(대부분의 언어들), '(ASP)으로 처리해 주시기 바랍니다.

또한, 변수에 관한 주석은 좌측에, 특정 로직에 대한 변수는 반드시 블럭상단에 blank line을 추가하신 후, 달아주시기 바랍니다.


6. 코드의 블럭화.

대부분의 언어들은 코드의 블럭설정을 지원합니다.

반드시, 로직에 따라 블럭을 지정해 주십시요.

블럭은 차후에, 다른 메서드&함수로 추출되고, 그 자리에는 해당 메서드를 호출하는 코드가 오면 됩니다.

즉, 당장은 바빠서 일일히 Extract Method를 적용하진 못한다 하더라도, 다른 개발자를 위해서, 또는 자신을
위해서 반드시 로직에 따른 블럭구분은 중요합니다.


데이터베이스의 네이밍은 더 각별합니다.

프로그램 소스는 유닛별로 수정을 가하면 그만이지만, DB는 불변합니다.

이건 너무 장황해서, 여기서 모든것을 설명할 순 없겠지만, 가장 핵심적인 거 몇가지만 부탁 드리겠습니다.

1. 테이블 네이밍.

테이블 네이밍에서는 예외적으로 _ 네이밍을 허용합니다.

order_sheet
order_product

또한 동일한 제품군에 속하는(예 : 쇼핑몰) 테이블이라면, 반드시 접두어를 붙여 주시기 바랍니다.

예 :

shop_order_sheet
shop_order_product

한 데이터베이스안에는 경우에 따라, 수십/수백개의 테이블이 생성됩니다.

일종의 패키지 개념과 마찬가지로, 반드시 테이블의 성격을 대변하는 공통된 접두어를 붙여주어, 이런 불행한 사태를 예방합시다.

또한, 가급적이면, list란 네이밍은 자제하여 주십시요.

엔티티타입(테이블) 자체가 list를 의미하기 때문입니다.

위의 예에서, order_sheet은 그렇다 치더라도, order_product의 경우는 한 주문서당 여러개의 주문상품이 포함되기 때문에,
list란 접미어를 붙이는 게 옳다고 생각되시겠지만, 전혀 그렇지 않습니다. (이에 대한 해결책은 ERD 상에서 카디낼러티 표기로
해결할 문제지, 네이밍과는 무관한 문제 입니다.)

또한, 세상에 존재하지 않는 단어, 공표되지 않은 약어, 한글발음식 영문표기등은 절대 피하셔야 합니다.

사실, str(String)과 같은 흔한 약어를 쓰시는 분들이 있는데, db, cpu, ram과 같은 약어와는 다르게 공표되지 않은 단어 입니다.

이러한 약어들의 사용을 점검해 보시기 바랍니다. (이건 코딩컨벤션에서도 동일하게 적용됩니다.)


또한 쿼리문의 경우도, 코드와 같이 들여쓰기를 유지하여 주십시요.

예제 1. 간단한 쿼리문

SELECT
*
FROM order_sheet

WHERE
orderID = "" AND
orderName = ""

ORDER BY
registerDate Desc


예제 2. 복잡한 쿼리문 (선택 필드의 수가 많아서, 여러 라인으로 분활 하였음을 눈여겨 봐주십시요.)


SELECT
a.merchantID, b.affiliateID, a.eventType, count(*) as totalCount,
sum(a.affiliateFee) as totalAffiliateFee, sum(a.masterFee) as totalMasterFee,
a.registerDate as registerDate, a.lastModifiedDate as lastModifiedDate

FROM
partnership_marketing_merchant_event_log a

LEFT JOIN partnership_marketing_client_banner_log b
ON a.clientID = b.clientID

LEFT JOIN partnership_marketing_banner c
ON b.bannerID = c.bannerID

WHERE
조건1... AND
조건2... AND
(조건3 OR 조건4) AND
( a.registerDate > $beginDate AND a.registerDate < $endDate )

GROUP BY
sortGroup


예제 3. 내용수정

UPDATE 테이블명

SET
필드1 = '',
필드2 = '',
필드3 = '',
필드4 = ''...

WHERE
조건식 ...


대충 이런식입니다. (CRM과 같은 데이터웨어 마이닝과 관련된 분야에서는 코딩컨벤션 보다, 쿼리문의 컨벤션을 더 중요시 합니다.)


기타...

필드명은, 실제 업무에서 쓰이는 용어로 작성 하십시요.
공통된 도메인을 지정하여 필드의 속성을 정하십시요. (예 : 가입일, 수정일, 방문일, 누적일등등은... "날짜형" 이란 공통된 도메인을 정의할 수 있습니다.
날짜형 => DATATIME 이라면, 새로운 필드를 추가하더라도, 기존의 도메인을 참고하여, 동일하게 속성을 주십시요. 이건 차후 유지보수에 있어서 큰 차이를 가져
옵니다. 기존에 도메인이 존재하지 않다면? 새롭게 추가된 속성에 맞추어 도메인을 정의하십시요. 반!드!시!)

아래는 전부 속성(필드)를 의미합니다.

예 : 아버지 이름, 어머니 이름, 딸 이름, 아들이름 => 한글이름 이란 도메인을 설정하고, varchar2(8)로 줍시다.
예 : managerName, employName, studentName => 영문이름 이란 도메인을 설정하고, varchar2(20)으로 줍시다.


나머지 것들...

파일네이밍 역시 엄청나게 중요합니다.


파일네이밍은 '_' <- 문자의 사용을 허용합니다.

예 :

partner_log_write
client_connect_page
...

파일의 경우는, 간단한 규칙이 있습니다.

대분류 -> 중분류 -> 식으로 분류를 정해주고...

마지막에는 이 파일이 주로 행하는 행동을 서술합니다.

예를들면,

partner -> 로그 -> write
(협력자)의 (로그)를 (작성)합니다.

client_connect_page
(고객)의 (접속) (페이지)


위의 파일네이밍에서 대분류->중분류->소분류가 지나치게 많다면?

디렉토리로 구분해 주면 됩니다.

partner란 디렉토리를 만들고...

log_write 란 파일을 집어넣으면 됩니다.

이건 디자이너 분들도 좀 읽어주면 좋을텐데요. ^^ (저도 취미삼아서 웹페이지를 종종 만드는데, 이미지의 경우도 위와 같은 네이밍 규칙에 따라서 배정한답니다. ㅋㅋㅋ)

(단, 클래스 파일의 경우는 클래스명과 동일하게 주시면 됩니다. 또한 클래스명 역시 대분류->중분류->소분류 식으로 이름을 줍니다. 이거 외에는 다르니, 혼돈하지 마세요.)


본인도 먹고 사는데 급급하다 보니, 본 문서를 언제 정리할지 모르겠네요.

우선은 가장 시급한 부분만 적어 놓았습니다.

앞으로 함께 일하게 될 여러분들. 특히 개발자 여러분들. (선배님들도 많이 계신데, 너무 날뛴 건 아닌가 부끄럽기도 합니다.)

제 글이 도움이 되실만한 분들에게만 당부 드리겠습니다. (즉, 저보다 수가 높으신 분들은 살짝 건너뛰시기 바랍니다.)

아무것도 아닌 것 같지만, 이런 컨벤션들이 가져다 주는 이익은 무한합니다. 이건 실제로 경험해 보기 전까지는 느낄 수 없는 짜릿함 이지요.

때론 객체, 절차지향이냐는 중요치 않습니다. 문제는 어떻게든 우리는 빨리 만들어야 한다는 것이고, 아이러니 하게도, 이렇게 빨리 만들어진 소스를 아주
효율적으로 개선시키고, 디버깅 하라는 주문을 자주 받지요.

이런 난관을 극복하기 위해선...

1. DB 모델링 서적의 탐독. (ERD는 프로젝트 기일을 오히려 축소 시켜준다. 믿기 힘들죠?)
2. 리팩토링에 관심을 가질 것. (리팩토링은 코딩과 함께 자연스럽게 해나가는 거지, "자! 리팩토링 좀 해볼까?" 라고 마음먹고 하는 것이 아닙니다.)
3. 디자인패턴에 관심을 가질 것.
4. PC ANYWHERE + 화상채팅등을 통해, 오랫동안 함께 일하게 될 파트너와 PAIR PROGRAMMING을 틈틈히 해볼것. (물론 옆자리에 나란히 앉아서 하면 더 좋지만, 자칫 오해 받을 수 있습니다. -_-)
5. UNIT TEST에 관심을 가질 것.

입니다.

무수한 방법론이 쏟아져 나오고 있지만, 위의 5가지만 어느정도 숙달되시면, 적어도 유지보수 문제로 인해 큰 좌절은 맛 보지 않으실 겁니다.

계속해서 제 글이 보강되고, 오류가 있다면 정정해 나가며, 함께 작업하는데 있어 아무런 혼란이 없기를 바랍니다. :-)

출처 : http://blog.naver.com/ndarkness75