반응형
Code Layout
개인 취향에 따라 다르다. 하지만 특정 규칙을 정해놓고, 통일성있게 작성하자.
Evidence that Layout Matters
- Chase & Simon (1973): "Preception in Chess"
- Schneiderman(1975): "Exploratory Experiments in Programmer Behavior"
- McKeiten et al. (1981)
- Soloway & Ehrlich (1984)
파이썬
- 래이아웃은 일등 시민이다
원칙과 목표
- 비주얼 레이아웃 -> 프로그램의 논리적 구조
- 목표: 코드를 예쁘게 만드는 것이 아닌 이해하기 쉽게 만든다.
- 다른 프로그래머들의 경험을 빌리자.
- 더욱 빠르게 전문가가 될 수 있음
- Withstand the test of time
- how to maintan layout and commnets as code evolves
- modifying one line shouldn't require changing many others
화이트 스페이스(공백 문자)
- 공백 문자는 그룹화를 위한 기반을 제공.
- 공백 문자는 문자를 이해하는데 아주 중요함.
- 들여쓰기(indentation)는 논리적인 구조를 보여줌. (탭(들여쓰기)은 2~4개의 스페이스가 적당)
괄호
- 계산 순서를 보여줌. 따라서 오해를 막을 수 있음
Code Layout (Classes)
클래스의 설계, 배치
- Header comment
- Class data
- Public methods
- Protected methods
- Private methods
Using Files
- interface, implementations를 파일로 분리
- 파일마다 하나의 클래스
- 클래스 이름을 먼저 짓고, 파일 이름을 정하라.
- 자바는 이런 방식 이미 사용중
- 클래스 이름을 위해서는 upper camel case(= PascalCase)를 사용할 것.(e.g., UpperCamelCase)
- 파일 내에서 메서드를 확실히 구별 가능하게 작성
- 최소한 2개의 빈 라인을 둬서 구분
Python PEP8 Naming
- 모듈 이름(파일 이름)은 short, all-lowercase이어야 하며, undercore(_)을 포함할 수 있다.
- 패키지 이름(디렉토리명)은 모듈 이름 조건과 동일하지만 underscore를 포함할 수 없다.
- 클래스는 CapWords 컨벤션을 따른다.
- CapWord* : 각 글자의 첫 글자를 대문자로.
포맷팅(Formmating)
- 코드 한 줄의 길이 <= 120개의 문자
- 120은 사실 너무 많고 일반적으로 80개 이내로 할 것.
- 클래스의 코드 줄 수 <= 2,000줄
- 최대한 적게.
Code Layout(Methods)
일반적인 구조
- 반환값 + 파라미터
- 예외(Exceptions)
- 여는 중괄호
- 메서드 본문
- 닫는 중괄호
파라미터
- 파라미터를 적을 때, 적용되는 tab 간격을 동일하게, 이쁘게 만드려고 임의로 탭간격을 다르게 할 필요 X
간단한 메서드
- 메서드를 작고 focused하게 유지
- 50줄이 넘어가면 restructuring을 고민할 것
- 150줄이 넘지 않도록 하라.
- 최대 7개의 파라미터
- 간단한 제어 흐름
- indirect(mutual) recusion을 피하자.
Code Layout (Statements)
Braces
- 여는 괄호는 이전의 statement와 같은 line에
- 닫는 괄호는 혼자 하나의 line을 사용
- 한 줄의 statement만 있더라도 brace를 사용.(for 문 또는 if 문에서)Statement Indentation
- use 2~4 spaces. 단위 정해서 하나만 사용Demarcate Blocks with whitespace
- 일부 블록들은 자연스럽게 구별이 되지 않을 수도 있음.
- 이럴때는 blank 라인을 이용해서 분리시키자.
- 코드 이해를 돕기 위한 것.
AAAAAA
AAA
AAAAA
BBB
BBBB
BB
CCCC
Alignment
- 쉼표 뒤에 한 칸 띄우기
- 배열 내부에 괄호와 한 칸 띄우기 or 붙여서 쓰기 등등
Split Complex Predicates Cleanly
- 너무 긴 or 복잡한 조건문은 이해하기 쉽게 분리하기.
Multi-Line Statements
- 아직 문장이 끝나지 않았음을 명시적으로 알 수 있도록 작성하거나
while (A < B &&
C < D)
/// ...
- 새로운 문장 시작 부분에 작성할 수도 있음
while (A < B
&& C < D)
/// ...
One Statement per Line
a = 0; b = 0; c = 0; print(a, b, c) # bad
Each Line Should Do One Thing
PrintMessage(++A, A+3) # bad
변수 이름 짓기
좋은 이름을 선택하기
- 변수 이름을 정할 때, 잘 생각해서 정해야 함.
- 의미 전달이 용이하게.
int birthdayDate;
int birthdayMonth;
int age;
이름 길이
- 디버깅 시간을 최소화할 수 있음 -> 이름의 길이가 10~16일 때.
- 짧은 이름이 명확하게 의미 전달이 되는지, 확인 할 것
- read-optimize! not write-optimize. 읽는 사람을 생각하라.
- 자주 사용하는 이름은 짧게, 자주 사용하지 않는 이름은 길게
반복문(루프) 인덱스
- 보통 i, j, k 등을 사용
- 루프 밖에서는 의미를 전달할 수 있는 이름을 사용하자.
루프 안에서 카운트 된 변수가 루프 밖에서도 사용된다면.
readCount = 0;
while (readBooks()) {
readCound++;
}
readingRate = readCount / booksTotal;
- 긴 반복문 내에서는 인덱스 이름을 더욱 잘 구별하기 위해서 full index name을 쓰자
- Avoid index cross talk in nested loops
- 보통 i, j를 쓰기에 헷갈리는 경우가 많음
- loop 인덱스로 i, j, k만을 사용하자. 그렇지 않으면 다른 개발자들이 코드를 볼 때, 헷갈릴 수 있음.
Computed-Value Qualifiers
- 자주 사용되는 것: Total, Sum. Average, Max, Min ...
- 변수 이름 마지막에 붙이자.
- booksTotal, readsAverage
- 에외: Num
- 접두사로 사용 (numUsers)
- 하지만 사용을 자제하기.(대신에 Count나 Total이라는 용어를 사용하자)(권장)
Use Common Opposites
- begin/end
- first/last
- locked/unlocked
- max/min
- next/previous
- old/new
- opened/closed
- visible/invisible
- source/target
- source/destiantion
- up/down
Purpose-Driven Naming
- 하나의 이름을 하나의 목적으로만 쓰기.
- tmp와 같은 변수명 사용 X
- Explicit names leads to clearer code
Status Variables
- Avoid using flag in the name
- it always means something, so name it accordingly
- Use explicit variable names instead
# Bad
flag = 0x1;
statusFlag = 0x80;
printFlag = 16;
computeFlag = 0;
#Good
dataReady = true;
characterType = CONTROL\_CHARACTER;
reportType = ReportType\_Annual;
recalcNeeded = false;
Avoid Hybrid Coupling
- 숨은 의미가 있는 변수를 사용하지 말 것.
- 예) bytesRead
- # of bytes received를 의미
- 0 보다 작을 경우 오류가 발생했음을 의미
Seperate NameSpaces
- Java packages
- can distinguish Database::Table from GUI::Table
- C++ namespace keyword
- 네임스페이스 기능이 없는 언어(C 언어)의 경우 naming convention을 이용
Use Enums Liberally
public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX,
SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }
Boolean Variables
- 일반적인 부울 이름을 사용
- done, error, found, success, ok, ...
- true/false 값만 가짐.
- Bad: status, sourceFile
- "is" 접두사를 사용하면 좋음.(isDone ...)
- 긍정적인 의미를 가진 이름 사용을 권장.
- isDone, isFail -> negate하기 좋음
- isNotDone, isNotFail -> negate하면 헷갈림.
Shortening Names
- Some abbreviation tricks
- remove non-leading vowels(모음) (screen -> scrn, pages => pgs)
- 한글에서 초성만 남기듯이
- remove articles(관사) (and, the, ...)
- remove useless endings (-ing, -ed, ...)
- remove non-leading vowels(모음) (screen -> scrn, pages => pgs)
- Abbreviate consistently (일관성)
- "Standard Abbreviations" 문서를 작성할 수도 있음.
- Should pass the telephone test
- 소리내어 읽어보며 테스트(잘 읽히는가?)
Data Declaration
- Put in comments what cannot go in name
- Put unambiguous units in name of variable(명확한 단위를 표현)
- if not possible, then at least put them in comments(불가능한 경우, 주석 첨부)Name to Avoid
- 소리가 비슷한 단어(wrap vs rap)
- telephone test!
- 최소한 2개의 문자가 달라야함
- 숫자 사용 X (num1, num2 ...)
- 흔히 저지르는 typo 조심
- 프로젝트에서는 1개의 언어(영어, 스페인어, 한국어 등등)을 사용하기.
Using Variables
Declarations & Initialization: Danger
- Improper init => fertile source of bugs
- result: variable has unexpected value
- Know your programming language’s semantics!
- Sources of bugs
- not initialized at all (default in Java, random in C/C++)
- inconsistent value (e.g., constructor initializes only part of the class)
Declarations & Initialization: what we can do
- 초기화와 선언을 가까이 두자.
- 선언과 초기화를 처음 사용하는 코드 라인과 가까이 위치
- Be disciplined with initialization
- 값을 명확하게 정해서 초기화 할 것. 언어에서 제공해준믄 default는 권장하지 않음
- 모든 클래스 멤버는 constructor에서 초기화
- method parameters: instead of initializing, these should be checked for validity
- 변수의 reassignment를 막기 위해 final, const 같은 것들을 활용하자
- constant를 원하는 경우 final static => init at class load time
Binding Variables to Values
- Binding vs. flexibility
- earlier binding -> less flexibility -> less complexity -> less risk of introducing errors
- later binding -> more flexibility -> more complexity -> more risk of introducing errors
- Can bind at
- Coding time (i.e., use magic values) (i.e.,
titleBar.color = 0xFF;
) - Compile time (i.e., use named constants)
-
private static final int TITLE_BAR_COLOR = 0xFF; titleBar.color = TITLE_BAR_COLOR;
- Run time (i.e, use properties file or Windows registry)
titleBar.color = windowProperties.getProperty("TITLE_BAR_COLOR");
- Object instantiation time: every time you create a window
- Just-in-time: every time you draw a window
- Coding time (i.e., use magic values) (i.e.,
Using Variables: Summary
- 내가 사용하는 프로그래밍 언어의 semantics를 숙지하고 사용
- 선언부 근처에서 초기화
- 처음 사용하는 곳 근처에 선언
- Flexibility vs. reliability trade-off
Variable Span, Liveness, and Scope
Variable Span
- space(LOC) between successive references
- Programs 아래 항목들을 가지고 있을 수 있다.
- 실행되긴 하지만, 전체적인 프로그램의 결과에 영향을 미치지 않는 코드.
- 정의, 선언되기 전에 사용되는 변수
- 메모리나 레지스터 할당이 필요한 변수
- variable liveness는 위의 3가지 상황을 다루기 위한 것임.
Variable Liveness
- Livenes는 변수의 property 중에서 데이터의 흐름에 관한 것.(“Is the value of this variable needed?”) (cf. dead code)
- 각각의 명령(instruction)에서 프로그램 안에 있는 변수는 live or dead인 상태
- 따라서 instruction의 시점에서 변수의 liveness를 따진다.
Semantic vs Syntatic
- 2가지 종류의 liveness
- Semantic liveness
- Syntactic liveness
- A variable x is semantically live at a node n if there is some execution sequence starting at n whose (externally observable) behavior can be affected by changing the value of x.
int x = y * z; # x는 live
return x;
int x = y * z; # x는 Dead
...
x = a + b;
...
return x;
반응형
'개발 > 학교 수업' 카테고리의 다른 글
[산업공학개론] 제조시스템의 설계 (2) (0) | 2021.10.26 |
---|---|
[산업공학개론] 제조 시스템의 설계 (1) (0) | 2021.10.25 |
[소개원실/swpp] Software Development Process (0) | 2021.10.12 |
[소개원실] Requirements and Specification (0) | 2021.10.07 |
[소개원실] Project Sprints (0) | 2021.10.07 |