코딩관계론

[Clean code] 형식 맞추기 본문

Clean code

[Clean code] 형식 맞추기

개발자_티모 2023. 1. 9. 22:35
반응형

형식을 맞추는 목적은 의사소통의 일환이기 때문이다. 또한 추후에 버전이 달라질때 유지보수와 확정성이 이점을 주기 때문이다.

형식을 맞추기 위해서는

  1. 적절한 행 길이를 유지해라 200~500
  2. 신문 기사처럼 작성하라
    1. 신문을 보면 위에서 요약하고 아래에 가면서 세세한 내용이 나탄다는 것을 기억해라
  3. 개념은 빈 행으로 분리하자
    1. 빈 행은 새로운 개념을 시작한다는 시각적 단서다.
// 빈 행을 넣지 않을 경우
package fitnesse.wikitext.widgets;
import java.util.regex.*;
public class BoldWidget extends ParentWidget {
	public static final String REGEXP = "'''.+?'''";
	private static final Pattern pattern = Pattern.compile("'''(.+?)'''",
		Pattern.MULTILINE + Pattern.DOTALL);
	public BoldWidget(ParentWidget parent, String text) throws Exception {
		super(parent);
		Matcher match = pattern.matcher(text); match.find(); 
		addChildWidgets(match.group(1));}
	public String render() throws Exception { 
		StringBuffer html = new StringBuffer("<b>"); 		
		html.append(childHtml()).append("</b>"); 
		return html.toString();
	} 
}
// 빈 행을 넣을 경우
package fitnesse.wikitext.widgets;

import java.util.regex.*;

public class BoldWidget extends ParentWidget {
	public static final String REGEXP = "'''.+?'''";
	private static final Pattern pattern = Pattern.compile("'''(.+?)'''", 
		Pattern.MULTILINE + Pattern.DOTALL
	);
	
	public BoldWidget(ParentWidget parent, String text) throws Exception { 
		super(parent);
		Matcher match = pattern.matcher(text);
		match.find();
		addChildWidgets(match.group(1)); 
	}
	
	public String render() throws Exception { 
		StringBuffer html = new StringBuffer("<b>"); 
		html.append(childHtml()).append("</b>"); 
		return html.toString();
	} 
}

4. 세로 밀집도

  • 줄바꿈이 개념을 분리한다면 새로 밀집도는 연관성을 의미한다
private int m_member = 0;
/**
* The properties of the reporter listener 
*/
private List<Property> m_properties = new ArrayList<Property>();
public void addProperty(Property property) { 
	m_properties.add(property);
}

의미 없는 주석으로 코드를 분리하지 말자

private int m_member = 0;
private List<Property> m_properties = new ArrayList<Property>();

public void addProperty(Property property) { 
	m_properties.add(property);
}

룰 3 적용으로 개념 분리

5. 수직거리

  • 연관성을 나타낸다. 연관성이란 한 개념을 이해하는데 다른 개념이 중요한 정도이다.
  • 변수 선언
int[] path;
/*
  doing other work;
  ;
  ;
  ;
*/

for(int i = 0; i < path.lengh(); ++i)
{
    //do work
}
/*
  doing other work;
  ;
  ;
  ;
*/
int[] path;
for(int i = 0; i < path.lengh(); ++i)
{
    //do work
}

아주 짧은 함수라면 변수 거리는 의미 없지만 지켜주는게 좋다

6. 종속함수

  • 한 함수 다른 함수를 호출한다면 두 함수ㄴ 세로로 가까이 배치한다.
  • 호출하는 함수를 호출되는 함수보다 먼저 배치한다
  • public class WikiPageResponder implements SecureResponder { 
    	protected WikiPage page;
    	protected PageData pageData;
    	protected String pageTitle;
    	protected Request request; 
    	protected PageCrawler crawler;
    	
    	public Response makeResponse(FitNesseContext context, Request request) throws Exception {
    		String pageName = getPageNameOrDefault(request, "FrontPage");
    		loadPage(pageName, context); 
    		if (page == null)
    			return notFoundResponse(context, request); 
    		else
    			return makePageResponse(context); 
    		}
    
    	private String getPageNameOrDefault(Request request, String defaultPageName) {
    		String pageName = request.getResource(); 
    		if (StringUtil.isBlank(pageName))
    			pageName = defaultPageName;
    
    		return pageName; 
    	}
    	
    	protected void loadPage(String resource, FitNesseContext context)
    		throws Exception {
    		WikiPagePath path = PathParser.parse(resource);
    		crawler = context.root.getPageCrawler();
    		crawler.setDeadEndStrategy(new VirtualEnabledPageCrawler()); 
    		page = crawler.getPage(context.root, path);
    		if (page != null)
    			pageData = page.getData();
    	}
    	
    	private Response notFoundResponse(FitNesseContext context, Request request)
    		throws Exception {
    		return new NotFoundResponder().makeResponse(context, request);
    	}
    	
    	private SimpleResponse makePageResponse(FitNesseContext context)
    		throws Exception {
    		pageTitle = PathParser.render(crawler.getFullPath(page)); 
    		String html = makeHtml(context);
    		SimpleResponse response = new SimpleResponse(); 
    		response.setMaxAge(0); 
    		response.setContent(html);
    		return response;
    	} 

7. 개념의 유사성

  • 개념적 친화가 높을 때 비슷한 위치에 배치한다(종속함수, 비슷한 동작함수)
  • public class Assert {
    	static public void assertTrue(String message, boolean condition) {
    		if (!condition) 
    			fail(message);
    	}
    
    	static public void assertTrue(boolean condition) { 
    		assertTrue(null, condition);
    	}
    
    	static public void assertFalse(String message, boolean condition) { 
    		assertTrue(message, !condition);
    	}
    	
    	static public void assertFalse(boolean condition) { 
    		assertFalse(null, condition);
    	} 

8. 들여쓰기

  • 범위 이뤄진 계층을 표현하기 위해 우리는 코드를 들여쓴다.
  • 필자는 한줄짜리 코드도 항상 들여쓰기를 습관화하여 가독을 높혔다.
public class CommentWidget extends TextWidget {
	public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
	
	public CommentWidget(ParentWidget parent, String text){super(parent, text);}
	public String render() throws Exception {return ""; } 
}
public class CommentWidget extends TextWidget {
	public static final String REGEXP = "^#[^\r\n]*(?:(?:\r\n)|\n|\r)?";
	
	public CommentWidget(ParentWidget parent, String text){
		super(parent, text);
	}
	
	public String render() throws Exception {
		return ""; 
	} 
}

제일 중요한 것은 팀규칙이다. 그래야 소프트웨어가 일관적인 스타일로 보인다

결론: 좋은 소프트웨어는 읽기 좋은 문서처럼 이루어져있다!

반응형

'Clean code' 카테고리의 다른 글

파이썬 데코레이터(Decorator)  (0) 2023.02.26
[Clean code] 클래스  (0) 2023.01.11
[Clean code] 자료추상화  (1) 2023.01.06
[Clean code] 함수  (0) 2023.01.04
[Clean Code] 코드에는 의미가 있어야 한다.  (1) 2023.01.03