티스토리 뷰
| 5. 형식 맞추기
--
|| 형식을 맞추는 목적
-
- 코드 형식은 중요하다. 코드 형식은 의사소통의 일환이다.
- 오늘 구현한 코드의 가독성은 앞으로 바뀔 코드의 품질에 지대한 영향을 미친다..
|| 적절한 행 길이를 유지하라.
-
- 적은 행 길이로도 커다란 시스템을 구축할 수 있다.
- 일반적으로 큰 파일보다 작은 파일이 이해하기 쉽다.
||| 신문 기사처럼 작성하라.
- 소스 파일도 신문 기사와 비슷하게 작성하자. 이름은 간단하면서도 설명이 가능하게 짓는다.
- 소스 파일 첫 부분은 고차원 개념과 알고리즘을 설명한다. 아래로 내려갈수록 의도를 세세하게 묘사.
마지막에는 가장 저차원 함수와 세부 내역
- 가장 중요한 개념을 가장 먼저 표현
||| 개념은 빈 행으로 분리하라.
- 빈 행은 새로운 개념을 시작한다는 시각적 단서이다.
||| 세로 밀집도
- 서로 밀접한 코드 행은 세로로 가까이 놓아야 한다.
1 2 3 4 5 6 7 | public class ReporterConfig { private String className; private List<Property> properties = new ArrayList<Property>(); public void addProperty(Property property) { properties.add(property); } } | cs |
||| 수직 거리
- 서로 밀접한 개념은 한 파일에 속해야 찾기 쉽다.
- 밀접한 두 개념은 세로 거리로 연관성을 표현한다.
> 변수 선언
- 사용하는 위치에 최대한 가까이 선언.
> 인스턴스 변수
- 클래스 맨 처음에 선언.
- 잘 설계한 클래스는 많은 클래스 메서드가 인스턴스 변수를 사용하기 때문.
> 종속 함수
- 한 함수가 다른 함수를 호출한다면 두 함수는 세로로 가까이 배치.
- 가능하다면 호출하는 함수를 호출되는 함수보다 먼저 배치
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 32 33 34 35 36 37 38 39 40 41 42 | 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); } // ... | cs |
|| 가로 형식 맞추기
-
- 120자 정도의 행 길이를 제한
> 가로 공백과 밀집도
- 가로로는 공백을 사용해 밀접한 개념과 느슨한 개념을 표현
1 2 3 4 5 6 7 | private void measureLine(String line) { lineCount++; int lineSize = line.length(); totalChars += line.length(); lineWidthHistogram.addLine(lineSize, lineCount); recordWidestLine(lineSize); } | cs |
> 들여쓰기
- 범위로 이루어진 계층을 표현하기 위해 코드를 들여씀.
- 짧은 함수에서도 들여쓰기로 범위를 제대로 표현하자.
|| 밥 아저씨의 형식 규칙
-
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | public class CodeAnalyzer implements JavaFileAnalysis { private int lineCount; private int maxLineWidth; private int widestLineNumber; private LineWidthHistogram lineWidthHistogram; private int totalChars; public CodeAnalyzer() { lineWidthHistogram = new LineWidthHistogram(); } public static List<File> findJavaFiles(File parentDirectory) { List<File> files = new ArrayList<File>(); findJavaFiles(parentDirectory, files); return files; } private static void findJavaFiles(File parentDirectory, List<File> files) { for (File file : parentDirectory.listFiles()) { if (file.getName().endsWith(".java")) files.add(file); else if (file.isDirectory()) findJavaFiles(file, files); } } public void analyzeFile(File javaFile) throws Exception { BufferedReader br = new BufferedReader(new FileReader(javaFile)); String line; while ((line = br.readLine()) != null) measureLine(line); } private void measureLine(String line) { lineCount++; int lineSize = line.length(); totalChars += lineSize; lineWidthHistogram.addLine(lineSize, lineCount); recordWidestLine(lineSize); } private void recordWidestLine(int lineSize) { if (lineSize > maxLineWidth) { maxLineWidth = lineSize; widestLineNumber = lineCount; } } public int getLineCount() { return lineCount; } public int getMaxLineWidth() { return maxLineWidth; } public int getWidestLineNumber() { return widestLineNumber; } public LineWidthHistogram getLineWidthHistogram() { return lineWidthHistogram; } public double getMeanLineWidth() { return (double)totalChars/lineCount; } public int getMedianLineWidth() { Integer[] sortedWidths = getSortedWidths(); int cumulativeLineCount = 0; for (int width : sortedWidths) { cumulativeLineCount += lineCountForWidth(width); if (cumulativeLineCount > lineCount/2) return width; } throw new Error("Cannot get here"); } private int lineCountForWidth(int width) { return lineWidthHistogram.getLinesforWidth(width).size(); } private Integer[] getSortedWidths() { Set<Integer> widths = lineWidthHistogram.getWidths(); Integer[] sortedWidths = (widths.toArray(new Integer[0])); Arrays.sort(sortedWidths); return sortedWidths; } } // Added to get code to build interface JavaFileAnalysis {} class LineWidthHistogram { public void addLine(int lineSize, int lineCount) { //TODO: Auto-generated } public Attributes getLinesforWidth(int width) { return null; //TODO: Auto-generated } public Set<Integer> getWidths() { return null; //TODO: Auto-generated } } | cs |
출처 : 클린 코드 (Robert C. Martin)
'Books' 카테고리의 다른 글
[클린 코드: Clean Code] 7. 오류 처리 (0) | 2021.01.13 |
---|---|
[클린 코드: Clean Code] 6. 객체와 자료 구조(Object and data structure) (0) | 2021.01.12 |
[클린 코드: Clean Code] 4. 주석(comment) (0) | 2021.01.11 |
[클린 코드: Clean Code] 3. 함수(Function) (0) | 2021.01.11 |
[클린 코드: Clean Code] 2. 의미 있는 이름(Meaningful name) (0) | 2021.01.10 |