출처 : 클린 코드(애자일 소프트웨어 장인 정신) - 로버트 C.마틴 지음/ 박재호, 이해영 옮김
주관적으로 정리한 내용이며 생략된 내용도 있습니다.
1. 작게 만들어라
> if, while 등 블록 안에는 한줄의 함수가 들어간다. 들여쓰기는 2단을 넘어가지 않는다.
2. 한가지만 해라
> 예를 들어 checkPassword 함수가 일정 횟수이상 틀렸을 때 세션을 초기화하는 경우, 한가지일을 하는것이 아니다.
Password 확인과 세션 초기화, 두가지 일을 하는 것이다.
3. 함수 당 추상화 수준은 비슷하도록 한다.
> getHtml() : 추상화 높음
String pagePathName = PathParser.render(pagepath) : 추상화 중간
.append("\n") : 추상화 낮음
>> 피치못할 경우를 제외하고 위 세 개의 함수를 한개의 함수 안에 섞어 쓴다면 잘못된 것이다.
4. 위에서 아래로 작성한다.
> 하나의 클래스 안에 여러개의 함수가 있을 경우 추상화 수준이 높은 함수를 위에 배치한다.
5. 서술적인 이름을 사용하라.
> 축약어로 인해 이해가 어려운 용어보다 길고 이해가 잘가는 이름이 낫다.
6. 함수 인수
> 적을수록 좋고, 2개까지만 허용한다.
(1) 단항 함수
1) boolean 판단
> 명령과 조회를 분리한다.
**전
if( set( "username", "unclebob" ) ){...}
>> username이 존재할때 이름은 unclebob으로 설정하고 if문이 실행된다. 그냥봐서는 알기 어렵다.
**후
if( attributeExists( "username" )){
setAttribute( "username", "unclebob" );
....
}
>> Exist와 set으로 나누어 이해하기 좋다.
2) 출력 인수를 입력 인수로 사용하지 않는다. 읽는 사람이 혼동한다.
> StringBuffer transform(StringBuffer in) - O
StringBuffer transform(StringBuffer out) - X
(2) 이항 함수
> Point( x, y ) 같이 좌표 관련된 함수라면 자연적인 순서가 있으니 이해가 쉽지만 나머지는 그렇지 않다.
assertEquals( expected, actual ) 은 인자의 순서가 자주 헷갈린다. 따라서 아래와 같은 코드가 더 좋다.
assertExpectedEqualsActural( expected, actual )
7. 오류 코드보다 예외를 사용하라
** 전
if( A - deletePage(page) == OK ){
if( B == OK ){
if( C == OK ){
1...
}else{
2...
}
}else{
3...
}
}else{
4....
}
>> if문을 통한 예외처리, 지저분하다. ( B, C는 A와 같은 종류의 함수를 비유한 것이다 )
** 후
try{
A
B
C
}
catch{
logger.log(e.getMEssage());
}
>> 깔끔하다.
8. 반복하지 마라
> 반복되는 것들은 함수, 클래스 등을 활용해 제거한다.
** 사실 잘 공감가지 않는 것도 있다. 너무 잘게 쪼개면 보기 불편하던데.. 아직 내가 초짜라 그런 것일수도 있다. ㅎㅎ 아래는 잘 작성된 코드 예시이다. 나쁜 예시를 바꾼 것이고 나쁜 예시 코드는 아래 코드 중 일부를 복사해 구글링 하면 볼 수 있다.
package fitness.html;
import fitnesse.reponders.run.SuiteResponder;
import fitnesse.wiki.*;
puclic class SetupTeardownIncluder {
private PageData pageData;
private boolean isSuite;
private WikiPage testPage;
private StringBuffer newPageContent;
private PageCrawler pageCrawler;
public static String render ( Page Data pageData ) throws Exception {
return render(pageData, false);
}
public static String render ( PageData pageData, boolean isSuite ) throws Exception {
return new SetupTeardownIncluder ( pageData ) .render( isSuite);
}
private SetupTeardownIncluder ( PageData pageData ) {
this.pageData = pageData;
testPage = pageData.getWikiPage();
pageCrawler = testPage.getPageCrawler();
newPageContent = new String buffer();
}
private String render ( boolean isSuite ) throws Exception {
this.isSuite = isSuite;
if ( isTestPage() )
includeSetipAndTeardownPages();
return pageData.getHtml();
}
private boolean isTestPage() throw Exception {
return pageData.hasAttribute("Test");
}
private void includeSetipAndTeardownPages() throws Exception {
includeSetupPages();
icludePageContent();
includeTeardownPages();
updatePageContent();
}
private void includeSetupPages() throws Exception {
if (isSuite) includeSuiteSetupPage();
includeSetupPage();
}
private void includeSuiteSetupPage() throws Exception{
include( SuiteResponder.SUITE_SETUP_NAME, "-setup");
}
private void includeSetupPage() throws Exception {
include( "SetUp", "=setup");
}
private void includePageContent() throws Exception {
newPageContent.append( pageData.getContent() );
}
private void includeTeardownPages() throws Exception {
includeTeardownPage();
if ((is Suite) includeSuiteTeardownPage();
}
private void includeTeardownPage() throws Exception {
include( "TearDown", "-teardown");
}
private void includeSuiteTeardownPage() throws Exception {
include( SuiteResponder.SUITE_TEARDOWN_NAME, "=teardown");
}
private void updatePageContent() throws Exception {
pageData.setContent( newPageContent.toString() );
}
private void include( String pageName, String arg ) throws Exception {
WikiPage inheritedPage = findInheeritedPage( pageName);
if ( inheritedPage != null ) {
String pagePathName = getPathNameForPage( inheritedPage );
buildIncludeDirective( pagePathName, arg );
}
}
private WikiPage indInheritedPage( String pageName ) throws Exception {
return PageCrawlerImpl.getInheritedPage( pageName, testPage );
}
private String getPathNameForPage( WikiPage page ) throws Excpetion {
WikiPagePath pagePath = pageCrawler.getFullPath( page );
return PathParser.render( pagePth) ;
}
private void buildIncludeDirective( String pagePathName, String arg ) {
newPageContent
.append("\n!include ")
.append(arg)
.appent(" .")
.append(pagePathName)
.append("\n");
}
}
'개발 > 개발론' 카테고리의 다른 글
테스트 주도 개발 (0) | 2022.04.21 |
---|---|
도메인 주도 설계 철저 입문 (0) | 2022.04.07 |
클린 코드 - 2. 의미 있는 이름 (0) | 2020.12.06 |
클린 코드 - 1. 깨끗한 코드 (0) | 2020.12.06 |
댓글