Upgrade to Pro — share decks privately, control downloads, hide ads and more …

preetyCode

JungWon2
September 24, 2013
1.1k

 preetyCode

fff

JungWon2

September 24, 2013
Tweet

Transcript

  1. 다음 중 이쁜 코드는? return exponent >= 0 ? mantissa

    * (1<<expnent) : mantissa / (1<< -expnent) If ( expnent >= 0) { return mantissa * ( 1 << exponent) } else { return mantissa / (1 << -exponent) } VS
  2. 무엇이 코드를 이쁘게 만드는가? 할머니에게 설명할 수 없다면 당신은 제대로

    이해한 것이 아니다. - 알버트 아이슈타인 프로그램을 수행하는 일을 설명하는 가장 주된 방법은 소스 코드. 코드 역시 쉬운 말로 작성 해야..
  3. 실제 작업이 이렇다면.. SendCharInfo(...) { 로그인 정보 변경 캐릭터 맵핑

    DB 갱신 ... 블라블라.. 캐릭터 정보 전송 } SetItemID(..) { 전 아이템을 모두 갱신 ...블라블라 모든 유저에게 라우팅 }
  4. 뭔가 모호한 이름들.. treeSize(..) =>트리의 노드 갯수 인가? 노드 깊이인가?

    getPage(url) 인터넷에서 페이지를 가져오는 건가? 로컬에서 가져오는 건가? bool read_password 패스워드를 읽을 필요가 있다는 건가? 패스워드가 읽었다는 건가?
  5. 이름에 정보를 담기 1. 가급적 보편적인 이름 피하기 Tmp, retval,

    foo, proc... 2. 추상적인 이름 대신 구체적인 이름. ServerCanStart() => CanListenOnPort() 3. 이름에 추가적인 정보를 담기 Start(int delay) => Start(int delay_secs)
  6. 4. 기대에 부흥하기 Get.. Set... , size() 가 하는 일,

    걸리는 시간 이름에 정보를 담기
  7. 적정한 이름의 길이 현재 긴 이름은 타이핑 상 문제가 되지

    않는 시대 NewNavigationControllerWrappingViewControllerForDataSurceOfClass NNClass
  8. 좁은 범위에서는 짧은 이름도 OK if(debug) { map<string, int> m;

    LookUpNamesNumbers(&m); print(m); } debug용 m의 생명주기는 딱 3줄 하지만, m이 멤버거나 전역변수라면..? LookUpNamesNumbers(&m); print(m);
  9. 약어와 축약 doc => document str => string ToString =>

    convertToString 아래는? BFG => ???!
  10. 사용범위가 넓다면 긴 이름을 사용하라 좁은 범위에 잠깐 사용하는 이름은

    짧게 사용하라 이름 길이에 대한 고찰 Code Complete에서 권하는 길이 일반적으로 10~16자, 8~20자 사이일 때, 디버깅이 용이했다.
  11. Class StatsKeeper { Public: /*일련의 더블변수값을 저장하는 클래스*/ Void Add(double

    d); Private: int count; double Average() Private : double minimum; list<double> past_items; double max; }; //일련의 더블 변수를 저장 //하는 클래스 Class StatsKeeper { Public: void Add(double d); double Average() Private: list<double> past_items; int count; double maximum; double minimum; }; 코딩의 미학
  12. 일관성과 간결성을 위해 줄 바꿈을 재정렬 하자 public static final

    TcpConnectionSimulator wifi = new TcpConnetcionSimulator(500, /* kbps */80,/*흔들림*/200, /* 흔들림 */1 /* 패킷 손실 % */); public static final TcpConnectionSimulator cell = new TcpConnectionSimulator( 4500, /* kbps */ 10, /* millisecs 대기시간*/ 0, /* 흔들림 */ 0 /* 패킷 손실 % */); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 4500, /* kbps */10, /* millisecs 대기시간*/ 250, /* 흔들림 */ 0 /* 패킷 손실 % */); public static final TcpConnectionSimulator wifi = new TcpConnetcionSimulator( 500, /* kbps */ 80, /*millisecs 대기시간*/ 200, /* 흔들림 */ 1, /* 패킷 손실 % */); public static final TcpConnectionSimulator cell = new TcpConnectionSimulator( 4500, /* kbps */ 10, /* millisecs 대기시간*/ 0, /* 흔들림 */ 0 /* 패킷 손실 % */); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 4500, /* kbps */ 10, /* millisecs 대기시간*/ 250, /* 흔들림 */ 0 /* 패킷 손실 % */); '비슷한 코드는 비슷하게 보여야 한다' 원리
  13. public static final TcpConnectionSimulator wifi = new TcpConnetcionSimulator( 500, /*

    kbps */ 80, /*millisecs 대기시간*/ 200, /* 흔들림 */ 1, /* 패킷 손실 % */); public static final TcpConnectionSimulator cell = new TcpConnectionSimulator( 4500, /* kbps */ 10, /* millisecs 대기시간*/ 0, /* 흔들림 */ 0 /* 패킷 손실 % */); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 4500, /* kbps */ 10, /* millisecs 대기시간*/ 250, /* 흔들림 */ 0 /* 패킷 손실 % */); '반복하지 말라(DRY)'는 원리 // TcpConnectionSimulator ( 처리량, 지연속도, 흔들림, 패킷 손실) // [kbps] [ms] [ms] [percent] public static final TcpConnectionSimulator wifi = new TcpConnetcionSimulator( 500, 80, 200, 1 ); public static final TcpConnectionSimulator cell = new TcpConnectionSimulator( 4500, 10, 0, 0 ); public static final TcpConnectionSimulator t3_fiber = new TcpConnectionSimulator( 4500, 10, 250, 0 );
  14. 코드를 문단을 쪼갠다. def suggest_new_friends(user, email_password): Friends = user.friends() friend_emails

    = set(f.email for f in friends) contacts = import_contacts(uiser.email, email_password) contact_emails = set(c.email for c incotacts) non_friend_emails = contact_email – friend_emails suggested_friends = User.objects.select(email_in=non_friend_emails) display['user'] = user display['friends']=friends Display['suggested_friends'] = suggested_frieds return render(“suggested_friedns.html”, display) def suggest_new_friends(user, email_password): #사용자 친구들의 이메일 주소를 읽는다. Friends = user.friends() friend_emails = set(f.email for f in friends) #이 사용자의 이메일 계정으로부터 모든 이메일 주소를 읽어 들인다. contacts = import_contacts(uiser.email, email_password) contact_emails = set(c.email for c incotacts) #아직 친구가 아닌 사용자들을 찾는다. non_friend_emails = contact_email – friend_emails suggested_friends = User.objects.select(email_in=non_friend_emails) #사용자 리스트를 화면에 출력한다. display['user'] = user display['friends']=friends Display['suggested_friends'] = suggested_frieds return render(“suggested_friedns.html”, display)
  15. 문단으로 쪼갰을 때 장점 비슷한 생각을 하나로 묶어서 다른 생각과

    구분된다. 문단은 시각적 디딤돌 역할을 한다. 하나의 문단에서 다른 문단으로 전진을 촉진 시킨다. 거대한 코드를 읽고 싶은 사람은 없다. 하지만 Extract Method 보다도, 가독성이 우선!!
  16. 이런 주석은 쓸모가 없다. //클래스 ACount를 위한 정의 Class Account

    { public: //생성자 Account(); //profit에 새 값 설정 void SetProfit(double profit); //이 카운트에 profit을 반환 double GetProfit(); }
  17. //해당 키를 위한 핸들을 놓아준다. //이 함수는 실제 레지스트리를 삭제하지

    않는다. void DeleteRegistry(RegistryKey* key) 이런 주석은 필요한 것 같지만, 실은 이름을 잘못 지은 문제 => void ReleaseRegistryHandle(RegistryKey *key) 주석따위!!! 난 소스로만 말한다! 왕년에 이런 아저씨들 많았다.
  18. // 이 데이터에서 이진트리는 해시테이블보다 40% 정도 빠름 // 해시를

    계산하는 비용이 좌/우 비교를 능가함 => 다른 사람이 불필요한 작업을 피할 수 있게 해준다. NUM_THREADS = 8 //이 상수 값은 2 * num_processors //값이다. => 상수 값이 결정된 사연을 알게 해준다. //외부 서비스 호출하여 이메일 서비스를 호출한다. //(1분 후 타임오버) void SendEmail(string to, string subject, string body) => 다른 사람이 쉽게 빠질 것 같은 함정을 경고한다.
  19. 코드 자체에서 재빨리 도출될 수 있는 사실 나쁜 함수명과 같이

    나쁘게 작성된 코드를 보정하려는 주석 달지 말아야 할 주석 코드가 특정한 방식으로 작성된 이유를 설명해주는 내용 코드에 담긴 결함, 개선 방향 등 어떤 상수가 특정 값을 갖게 된 '사연' 필요한 주석
  20. 주석을 잘 달려면... 읽는 사람 입장에서 => 궁금해 할 내용을..

    => 쉽게 빠질 것 같은 함정을.. => 큰 그림에 대한 주석을.. 명확하게, 간단하게, 개괄적으로 설명 KISS (Keep It Simple! Stupid!) 원칙
  21. 흐름제어에 대한 가독성 If (a == b){ //첫번 째 경우

    }else { //두번 째 경우 } If (a != b){ //두번 째 경우 }else { //첫번 째 경우 } 어느 것이 가독성에서 유리할까?
  22. 흐름제어에 대한 가독성 -부정이 아닌 긍정을 다루는 것이 유리함. -간단한

    것을 먼저 처리하는 것이 유리함. -더 흥미롭고, 확실한 것을 먼저 다루는 것이 유리함. If (a == b){ //첫번 째 경우 }else { //두번 째 경우 } If (a != b){ //두번 째 경우 }else { //첫번 째 경우 }
  23. If, while, for문의 동작원리와 역순인 do/while 문은 코드를 2번 읽어야

    함. 부자연스럽다. 꺼려야할 do/while do { continue; } while (false) 내 경험으로 에러와 혼동의 원인은 do문에 있다. 그래서 나는 조건이 '눈에 뜨이는 곳에 미리' 나타나는 것을 선호한다.
  24. 인간 스택이 되어보자 if(isOpen()){ if(bSetup==true){ nCnt = MIN_SUM; } else{

    if(nSum <5){ nCnt = 6; } else{ nCnt = 10; } } } else{ return nCnt = -1; } return nCnt;