Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- BFS
- JPA
- ipo 매매자동화
- 아키텍쳐 개선
- 검색어 추천
- 크롤링
- 프로그래머스
- 디버깅
- 백준
- next-stock
- ai agent
- 추천 검색 기능
- AWS
- 구현
- langgraph
- 완전탐색
- 트랜잭샨
- 결제서비스
- jwt 표준
- 몽고 인덱스
- piplining
- 누적합
- 셀러리
- docker
- 쿠키
- spring event
- 레디스 동시성
- 이분탐색
- 카카오
- gRPC
Archives
- Today
- Total
코딩관계론
[Clean code] 형식 맞추기 본문
반응형
형식을 맞추는 목적은 의사소통의 일환이기 때문이다. 또한 추후에 버전이 달라질때 유지보수와 확정성이 이점을 주기 때문이다.
형식을 맞추기 위해서는
- 적절한 행 길이를 유지해라 200~500
- 신문 기사처럼 작성하라
- 신문을 보면 위에서 요약하고 아래에 가면서 세세한 내용이 나탄다는 것을 기억해라
- 개념은 빈 행으로 분리하자
- 빈 행은 새로운 개념을 시작한다는 시각적 단서다.
// 빈 행을 넣지 않을 경우
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 |