읽기 좋은 코드가 좋은 코드다(더스팀 보즈웰, 트레버 파우커 지음, 임백준 옮김) 를 읽고 자주 참고하면서 습관화하려는 부분을 정리해 놓은 것으로 좀 더 자세한 내용은 책을 보기 바랍니다. |
point. 좋은 소스코드는 '눈을 편하게' 해야 한다.
- 읽기 편한 소스코드를 작성하는 세 가지 원리
- 코드를 읽는 사람이 이미 친숙한, 일관성 있는 레이아웃을 사용하라.
- 비슷한 코드는 서로 비슷해 보이게 만들어라.
- 서로 연관된 코드는 하나의 블록으로 묶어라.
일관성과 간결성을 위해서 줄 바꿈을 재정렬하기 |
before
public class PerformanceTester { public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); }after
public class PerformanceTester { public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator( 500, // Kbps 80, // millisecs 대기시간 200, // 흔들림 1 // 패킷 손실 ); }
public class PerfoemanceTester { // TcpConnectionSimulator (처리량, 지연속도, 흔들림, 패킷 손실) // [Kbps] [ms] [ms] [percent] public static final TcpConnectionSimulator wifi = new TcpConnectionSimulator(500, 80, 20, 1); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator(45000, 0, 0, 0); public static final TcpConnectionSimulator cell = new TcpConnectionSimulator(100, 400, 250, 5);
메소드를 활용하여 불규칙성을 정리하라 |
before
DatabaseConnection database_connection; string error assert(ExpandFullName(database_connection, "Donug Adams", &error) == "Mr, Douglas Adms"); assert(error == ""); assert(ExpandFullName(database_connection, "Jake Brown", &error) == "Mr, Jacob Brown III"); assert(error == ""); assert(ExpandFullName(database_connection, "No Such Guy", &error) == ""); assert(error == "no match found"); assert(ExpandFullName(database_connection, "John", &error) == ""); assert(error == "more than one result");
afrer
- 중복된 코드를 없애서 코드를 더 간결하게 한다.
- 이름이나 에러 문자열 같은 테스트의 중요 부분들이 한 눈에 보이게 모아졌다. 수정 전에는 database_connection이나 error 같은 토큰들과 섞인 채 흩어져 있었기 때문에 코드를 한 눈에 파악하기 어려웠다.
- 새로운 테스트 추가가 훨씬 쉬워졌다.
void CheckFullNAme(string partial_name, string expected_full_name, string expected_error) { // database_connection은 이제 클래스 맴버이다. string error; string full_name = ExpandFullName(database_connection, partial_name, &error); assert(error == expected_error); assert(full_name == expected_full_name); } CheckFullName("Doug Adams", "Mr. Douglas Adams", ""); CheckFullName("Jake Brown", "Mr. Jake Brown III", ""); CheckFullName("No Such Guy", "", "no match found"); CheckFullName("John", "", "more than one result");
도움이 된다면 코드의 열을 맞춰라 |
after
details = request.POST.get('details'); location = request.POST.get('location'); phone = request.POST.get('phone'); email = request.POST.get('email'); url = request.POST.get('url');
의미 있는 순서를 선택하고 일관성 있게 사용하라 |
- 변수의 순서를 HTML 폼에 있는 <input> 필드의 순서대로 나열하라.
- '가장 중요한 것'에서 시작해서 '가장 덜 중요한 것'까지 순서대로 나열하라.
- 알파벳 순서대로 나열하라.
선언문을 블록으로 구성하라 |
before
class FrontendServer { public: FrontendServer(); void ViewProfile(HttpRequest* request); void OpenDatabase(string location, string user); void SaveProfile(HttpRequest* request); string ExtractQueryParam(HttpRequest* request, string param); void ReplyOK(HttpRequest* request, string html); void closeDatabase(string location); }
after
class FrontendServer { public: FrontendServer(); ~FrontendServer(); // 핸들러들 void ViewProfile(HttpRequest* request); void SaveProfile(HttpRequest* request); // 질의/응답 유틸리티 string ExtractQueryParam(HttpRequest* request, string param); void ReplyOK(HttpRequest* request, string html); // 데이터베이스 헬퍼들 void OpenDatabase(string location, string user); void closeDatabase(string location); }
코드를 '문단'으로 쪼개라 |
- 비슷한 생각을 하나로 묶어서, 성격이 다른 생각과 구분한다.
- 문단은 '시각점 디딤돌'역할을 수행한다. 문단이 없으면 하나의 페이지 안에서 읽던 부분을 놓치기 쉽다.
- 하나의 문단에서 다른 문단으로의 전진을 촉진시킨다.
after
def suggest_new_friends(user, email_password): # 사용자 친구들의 이메일 주소를 읽는다. friends = user.friends() friend_emails = set(f.email for f in friends) # 이 사용자의 이메일 계정으로부터 모든 이메일 주소를 읽어들인다. contacts = import_contacts(user.email, email_password) contact_emails = set(c.email for c in contacts) # 아직 친구가 아닌 사용자들을 찾는다. non_friend_emails = contact_emails - friend_emails suggested_friends = User.objects.select(email_in=non_friend_emails) ... return render("suggested_friends.html", display)
- 일관성 있는 스타일은 '올바른' 스타일보다 더 중요하다.
'대학 생활 > Develop' 카테고리의 다른 글
[운영체제]병행성, 임계구역, 상호배제, 교착상태 (0) | 2014.06.02 |
---|---|
Bitbucket 무료 gif 사이트 (0) | 2014.05.20 |
TCP/UDP 각종 포트 정리 (0) | 2014.04.13 |
출발지, 목적지 포트확인 - 엑셀 IF, AND, OR 수식 적용하기 (0) | 2014.02.25 |