CODE COMPLETE
CHAPTER 19
CHAPTER 20
Han-byeol Jeon
GENERAL CONTROL ISSUES
일반적인 코드 작성 이슈
Chapter 19
BOOLEAN
Boolean - bad
 If ( feelGood == 1 )
 Shout();
 If ( feelGood == 0 )
 Cry();
Boolean - better
 If ( feelGood == true )
 Shout();
 If ( feelGood == false )
 Cry();
 명시적 Boolean Expression
Boolean - best
 If ( feelGood )
 Shout();
 If ( !feelGood )
 Cry();
 암시적 Boolean Expression
 마치 그냥 글 같다!( 가독성 Good )
 But, 언어에서 지원해 주어야.(안해주면 명
시적으로라도)
복잡한 테스트를 쪼개라
 If( 배에서 꼬르륵 소리가 남 && 체한건 아님 ||
CBT중임 && Crash && 내 버그 ||
오늘 전체 야근 공지 && 저녁 여자친구 약속 ||
… )
 Shout();
 Bool hungry = 배에서 꼬르륵 소리가 남 && …;
Bool stressful = CBT 중임 && …;
if( hungry && stressful ) Shout();
 훨씬 읽기 좋다
복잡한 표현식을 함수에 넣어라
 가독성
 중복X
 If( Hungry() ) // if (배에서 꼬르륵 소리가 남 && 체한건 아님 )
 Eat();
 If( HasWayTo Go () )
 If( Hungry() ) //if (배에서 꼬르륵 소리가 남 && 체한건 아님 )
 Stop();
 Cry();
 유지 보수
 Hungry ()
 {
 Return (배에서 꼬르륵 소리가 남 && 체한건 아님 || 야근중 );
 }
복잡한 조건들을
decision table화 하라
 그러면 좋을 때도 있다!
 Chapter 18 참조
 코드가 매우 단순하다.
 데이터 코드(혹은 데이터)의 내용만 바꾸면 된다.
 시스템적 코드는 내비두고!
Decision table 예제( ><… )
void Agent::SetupPath( const AgentProperty& property )
{
PathType::Enum type = IdentifyPathType( property );
switch( type )
{
case PathType::Linear:
{
m_currentPath = m_pathTable[ PathType::Linear ];
}break;
case PathType::Agent:
{
m_currentPath = m_pathTable[ PathType::Agent ];
AgentPath* agentPath = static_cast< AgentPath* >( m_currentPath.get() );
agentPath->Clearance( m_property.Clearance() );
agentPath->Radius( m_property.Radius() );
agentPath->ObstalceCollision( m_property.AvoidObstacle() );
if( m_property.Curve() )
agentPath->CurveRadius( m_property.CurveRadius() );
else
agentPath->CurveRadius( m_property.Radius() );
agentPath->Reachable( m_property.Reachable() );
}break;
default:
BsAssert( false && "path type[%d] doesn't exist", type );
break;
}
}
PathType::EnumAgent::IdentifyPathType( constAgentProperty& property )
{
if( property.AvoidEdge() || property.AvoidObstacle() )
{
return PathType::Agent;
}
else
{
return PathType::Linear;
}
}
m_currentPath->FindPath( position );
m_currentPath->Interpolate( distance );
긍정적인 Boolean
 “I ain’t not no undummy” – Homer Simpson
 “I’m dummy”
 가독성의 문제
 If else 구문의 경우 긍정의 case를 먼저(true
state)
 If statusOK
 Do A;
 Else
 Do B;
 하지만 에러 처리의 경우?
 If ErrorDetected, If Blocked, If Sad
 Do ErrorProcess
드모르간의 법칙을 이용하라
 단순화와 가독성을 위해
괄호를 잘 쳐라
 가독성!!
 명시화는 습관
 A < B == C == D -> (A < B) == (C == D)
Boolean Expression
Evaluation
 AND
 If( HasMoney() && BuyFood( FoodType::Banana) )
 Eat( GetFood() );
 OR
 If( HasMoney() || EarnMoney() )
 BuyFood(FoodType::Banana);
 “Lazy Evaluation”
 현대 언어에서는 대부분 지원하지만 그렇지 않
은 언어도 있다.
 따라서 프세우도 코드에서는 명시화하는 것이 좋
음.
숫자 표현식은 오름차순으로
 If level < 30
 If 20 <= level && level < 30
 If 30 <= level
 If level < 5 || 25 < level
 시각화하기가 쉽다.
다양한 의미의 숫자 0..
0보다는 의미에 맞게!
 Boolean에서의 0 == false
 암시적으로 변환해서 사용하자.
 Numbers에서의 0 == 0
 0 그대로 쓰자.
 문자열에서의 0 == ‘0’
 ‘0’로 쓰자.
 Pointers에서의 0 == NULL
 NULL로 쓰자.
 왜?
 가독성을 위해서
Boolean Expressions에서의
일반적인 문제들
 C기반의 언어에서
 항등 비교시 상수를 왼편에 쓰자
 Java에서
 A == B 대신 A.equals(B)를 쓰자.
COMPOUND STATEMENTS(BLOCK)
BLOCK란?
 { }로 묶인 statement들.
조건문과 Block
 Statement가 하나인 조건문에도 괄호를 쓰
자.
 안그러면 유지보수할때 에러 발생하기 쉽다.
 Statement 추가시
 Else문 추가시
 If 문 추가시
 …
NULL STATEMENTS
Null statements == 빈 Block
 비었음을 명시해라.
 DoNothing() 매크로나 인라인 함수를 만들고 호
출하라.
 가독성이나 효율성을 많이 향상 시키는게
아니면 왠만하면 피해라.
 혼란스럽다..
 유지보수시 에러발생 확률 높다.
심하게 중첩된 Block
 대부분의 사람들은 중첩된 if가 3개가 넘어
가면 혼수상태
심하게 중첩된 Block 길들이기
 조건을 다시 테스트해서 줄인다.
 Do { 조건: break; } while(FALSE);를 사용해 줄인다.
 If 문들을 if-elseif-else문들로 바꾼다.
 Switch –case를 사용한다.
 심하게 중첩된 부분을 루틴으로 뺀다.
 객체와 다형성을 이용한다.
 아해 다시 짠다.
 “복잡한 코드는 그 코드를 단순화 할 수 있을 만큼 이해하고 있
지 않기 때문이다.”
 루틴 종료 방어 구문을 사용한다.
 예외를 사용한다.
 상태 변수를 사용한다.
구조화된 프로그래밍
STRUCTURED PROGRAMMING
핵심
 One-in, one-out
 한곳에서 시작해서 한곳에서 끝난다.
 반대 개념
 Break
 Continue
 Throw
 Catch
 Return
 …
3가지 구성요소
 순차
 순차적으로 실행
 선택
 선택된 부분만 실행( IF, SWITCH )
 반복
 반복적으로 실행( FOR,WHILE )
“반대 개념”들?
깊이 생각하고 사용하자.
 순차, 선택, 반복이면 충분하다!
CONTROL STRUCTURES
AND COMPLEXITIY
프로그래밍 복잡도
Programming complexity
 프로그램을 이해하기 위해서 얼마나 많은
것들을 동시에 생각해야 하는가.
 보통 사람들은 5 ~ 9가지 이상 생각하기 어
렵다.
복잡도 측정하기( 한가지 방법 )
 Statement가 하나라도 있으면 기본 1부터 시작.
 분기점( decision points )의 개수를 더한다.
 분기점이란?
 If, while, for, and, or, case
 6개 이상
 단순화 시킬 준비해라.
 10개 초과
 단순화 해라
 하지만 절대적인 것이 아님.
 특히 case마다 하나씩 세라는 것은 상황의존적인 부
분.
THE SOFTWARE QUALITY
LANDSCAPE
소프트웨어 품질에 대한 조명
Chapter 20
소프트웨어 품질의 요소
외부적 요소( 사용자 중심 )
 Correctness – 디자인에 부합한가
 Usability – 배우고 사용하기 쉬운가
 Efficiency – 효율적으로 실행되는가
 Reliability – 요구사항에 맞게 동작하는가
 Integrity – 결점 없이 동작하는가
 Adaptability – 수정 없이 다양한 환경에서 실
행되는가
 Accuracy – 정확한 결과를 도출하는가
 Robustness – 시스템이 안 뻗는가.
내부적 요소( 개발자 중심 )
 Maintainability – 얼마나 유지보수하기 좋은
가
 Flxibility – 얼마나 확장하기 좋은가
 Portability -얼마나 이식하기 좋은가
 Reusability – 재사용성이 좋은가
 Readability – 코드의 가독성이 좋은가
 Testability – 테스트하기 좋은 구조인가
 Understandability – 시스템의 구조를 이해하
기 쉬운가
소프트웨어 품질의 특성
 한 요소를 만족시키면
 다른 요소도 같이 좋아진다
 다른 요소가 나빠진다
 다른 요소에 아무 지장이 없다
 요소간의 이러한 상관관계를 기억하면 품질
목표를 정할 때 좋다.( Figure 20-1 )
소프트웨어 품질 향상을 위한
테크닉
테크닉 1
 소프트웨어 품질 목표를 정하라
 그렇지 않으면 프로그래머들이 서로 다른 품질 우선
순위를 갖고 코딩한다.
 모든 목표를 만족시키는 것은 불가능하다.
 품질 보장 활동을 명시하라
 품질 보장 목표를 널리~널리~ 알리고 인지시켜라
 안정성을 위해 테스트 전략을 잘 짜라
 소프트웨어 엔지니어링 가이드라인을 잘 짜라
 이 책도 하나의 가이드라인
테크닉 2
 비형식적인 기술 리뷰를 해라
 그냥 혼자 하는거
 공식적 기술 리뷰를 해라
 BVT 테스트( 품질 보장 허들 )
 100%가 아닌 “충분한” 정도를 넘어야 함.
 충분한 정도는 소프트웨어의 고유특성에 따라 다
름
 외부 청중에게 리뷰 받아라.
개발 절차
 변화를 컨트롤하는 처리절차
 요구사항의 변화를 통제하지 못하면 디자인과
코드를 손상시킨다.
 아키텍처의 변화
 중간/최종 결과 평가
 계획 진행 과정 평가
 소프트웨어의 품질 요소 평가
 개선과 재계획을 위해
 프로토타이핑
 핵심적 기능의 실현 가능성을 알아보기 위해
상대적 효율성을 가진
품질 보장 테크닉
결함 발견율
 보통 기업들
 테스트 중심
 결함 제거율 85%
 선도 기업들
 다양한 기술 조합
 결함 제거율 95%
 코드 읽기는 인터페이스 결함을
테스트는 로직 통제 결함을
 Extreme Programming( table 20-3 )
 최대 97%의 결함 제거율
인스펙션(코드 리딩)과 테스팅
 인스펙션이 테스팅보다
 비용이 적다.
 인스펙션은 1번만 보면 된다.
 테스팅은 테스트, 결과 보기, 결함찾기까지 해야한다.
 결함 발견 확률이 높다.
 그래도 Best는? 다 하기
 시스템의 중요한 부분에 있어 요구사항, 디자인, 아
키텍처 인스펙션하기.
 모델링 혹은 프로토타이핑 해보기
 인스펙션( 코드리딩 ) 하기
 테스팅하기
품질 보장은 언제 하는가
가능한 한 일찍!
 소프트웨어 개발주기의 아래에서 위로 올라
가는 것은 비용이 훨씬 크다.
 위에서 최대한 많은 결함을 확인하라.
 요구사항, 아키텍처.
소프트웨어 품질의
일반적인 원칙
 생산성과 품질 향상은 다시 코딩하는 시간
을 최대한 줄이는 것.
 그 원인이 요구사항의 변화든 디자인의 변화든
디버깅이든
 개발에 있어 가장 많은 시간이 드는 것은 디
버깅과 리펙토링
 총 개발 시간의 50%
 이 시간을 줄이는 것이 소프트웨어 품질을 향상
시키는 핵심
 즉 얼마나 적은 결함을 만드느냐
요약
 싸게 예방할 것인가
비싸게 고칠 것인가
 품질 목표를 정하고 널리~널리~ 알려라
 결함 발견에 다양한 기술을 접목하라
 결함은 가능한 한 일찍 발견하라
끗~ Q & A
수고하셨습니다.

Code complete chapter 19, 20 organize

  • 1.
  • 2.
    GENERAL CONTROL ISSUES 일반적인코드 작성 이슈 Chapter 19
  • 3.
  • 4.
    Boolean - bad If ( feelGood == 1 )  Shout();  If ( feelGood == 0 )  Cry();
  • 5.
    Boolean - better If ( feelGood == true )  Shout();  If ( feelGood == false )  Cry();  명시적 Boolean Expression
  • 6.
    Boolean - best If ( feelGood )  Shout();  If ( !feelGood )  Cry();  암시적 Boolean Expression  마치 그냥 글 같다!( 가독성 Good )  But, 언어에서 지원해 주어야.(안해주면 명 시적으로라도)
  • 7.
    복잡한 테스트를 쪼개라 If( 배에서 꼬르륵 소리가 남 && 체한건 아님 || CBT중임 && Crash && 내 버그 || 오늘 전체 야근 공지 && 저녁 여자친구 약속 || … )  Shout();  Bool hungry = 배에서 꼬르륵 소리가 남 && …; Bool stressful = CBT 중임 && …; if( hungry && stressful ) Shout();  훨씬 읽기 좋다
  • 8.
    복잡한 표현식을 함수에넣어라  가독성  중복X  If( Hungry() ) // if (배에서 꼬르륵 소리가 남 && 체한건 아님 )  Eat();  If( HasWayTo Go () )  If( Hungry() ) //if (배에서 꼬르륵 소리가 남 && 체한건 아님 )  Stop();  Cry();  유지 보수  Hungry ()  {  Return (배에서 꼬르륵 소리가 남 && 체한건 아님 || 야근중 );  }
  • 9.
    복잡한 조건들을 decision table화하라  그러면 좋을 때도 있다!  Chapter 18 참조  코드가 매우 단순하다.  데이터 코드(혹은 데이터)의 내용만 바꾸면 된다.  시스템적 코드는 내비두고!
  • 10.
    Decision table 예제(><… ) void Agent::SetupPath( const AgentProperty& property ) { PathType::Enum type = IdentifyPathType( property ); switch( type ) { case PathType::Linear: { m_currentPath = m_pathTable[ PathType::Linear ]; }break; case PathType::Agent: { m_currentPath = m_pathTable[ PathType::Agent ]; AgentPath* agentPath = static_cast< AgentPath* >( m_currentPath.get() ); agentPath->Clearance( m_property.Clearance() ); agentPath->Radius( m_property.Radius() ); agentPath->ObstalceCollision( m_property.AvoidObstacle() ); if( m_property.Curve() ) agentPath->CurveRadius( m_property.CurveRadius() ); else agentPath->CurveRadius( m_property.Radius() ); agentPath->Reachable( m_property.Reachable() ); }break; default: BsAssert( false && "path type[%d] doesn't exist", type ); break; } } PathType::EnumAgent::IdentifyPathType( constAgentProperty& property ) { if( property.AvoidEdge() || property.AvoidObstacle() ) { return PathType::Agent; } else { return PathType::Linear; } } m_currentPath->FindPath( position ); m_currentPath->Interpolate( distance );
  • 11.
    긍정적인 Boolean  “Iain’t not no undummy” – Homer Simpson  “I’m dummy”  가독성의 문제  If else 구문의 경우 긍정의 case를 먼저(true state)  If statusOK  Do A;  Else  Do B;  하지만 에러 처리의 경우?  If ErrorDetected, If Blocked, If Sad  Do ErrorProcess
  • 12.
    드모르간의 법칙을 이용하라 단순화와 가독성을 위해
  • 13.
    괄호를 잘 쳐라 가독성!!  명시화는 습관  A < B == C == D -> (A < B) == (C == D)
  • 14.
    Boolean Expression Evaluation  AND If( HasMoney() && BuyFood( FoodType::Banana) )  Eat( GetFood() );  OR  If( HasMoney() || EarnMoney() )  BuyFood(FoodType::Banana);  “Lazy Evaluation”  현대 언어에서는 대부분 지원하지만 그렇지 않 은 언어도 있다.  따라서 프세우도 코드에서는 명시화하는 것이 좋 음.
  • 15.
    숫자 표현식은 오름차순으로 If level < 30  If 20 <= level && level < 30  If 30 <= level  If level < 5 || 25 < level  시각화하기가 쉽다.
  • 16.
    다양한 의미의 숫자0.. 0보다는 의미에 맞게!  Boolean에서의 0 == false  암시적으로 변환해서 사용하자.  Numbers에서의 0 == 0  0 그대로 쓰자.  문자열에서의 0 == ‘0’  ‘0’로 쓰자.  Pointers에서의 0 == NULL  NULL로 쓰자.  왜?  가독성을 위해서
  • 17.
    Boolean Expressions에서의 일반적인 문제들 C기반의 언어에서  항등 비교시 상수를 왼편에 쓰자  Java에서  A == B 대신 A.equals(B)를 쓰자.
  • 18.
  • 19.
    BLOCK란?  { }로묶인 statement들.
  • 20.
    조건문과 Block  Statement가하나인 조건문에도 괄호를 쓰 자.  안그러면 유지보수할때 에러 발생하기 쉽다.  Statement 추가시  Else문 추가시  If 문 추가시  …
  • 21.
  • 22.
    Null statements ==빈 Block  비었음을 명시해라.  DoNothing() 매크로나 인라인 함수를 만들고 호 출하라.  가독성이나 효율성을 많이 향상 시키는게 아니면 왠만하면 피해라.  혼란스럽다..  유지보수시 에러발생 확률 높다.
  • 23.
    심하게 중첩된 Block 대부분의 사람들은 중첩된 if가 3개가 넘어 가면 혼수상태
  • 24.
    심하게 중첩된 Block길들이기  조건을 다시 테스트해서 줄인다.  Do { 조건: break; } while(FALSE);를 사용해 줄인다.  If 문들을 if-elseif-else문들로 바꾼다.  Switch –case를 사용한다.  심하게 중첩된 부분을 루틴으로 뺀다.  객체와 다형성을 이용한다.  아해 다시 짠다.  “복잡한 코드는 그 코드를 단순화 할 수 있을 만큼 이해하고 있 지 않기 때문이다.”  루틴 종료 방어 구문을 사용한다.  예외를 사용한다.  상태 변수를 사용한다.
  • 25.
  • 26.
    핵심  One-in, one-out 한곳에서 시작해서 한곳에서 끝난다.  반대 개념  Break  Continue  Throw  Catch  Return  …
  • 27.
    3가지 구성요소  순차 순차적으로 실행  선택  선택된 부분만 실행( IF, SWITCH )  반복  반복적으로 실행( FOR,WHILE )
  • 28.
    “반대 개념”들? 깊이 생각하고사용하자.  순차, 선택, 반복이면 충분하다!
  • 29.
  • 30.
    프로그래밍 복잡도 Programming complexity 프로그램을 이해하기 위해서 얼마나 많은 것들을 동시에 생각해야 하는가.  보통 사람들은 5 ~ 9가지 이상 생각하기 어 렵다.
  • 31.
    복잡도 측정하기( 한가지방법 )  Statement가 하나라도 있으면 기본 1부터 시작.  분기점( decision points )의 개수를 더한다.  분기점이란?  If, while, for, and, or, case  6개 이상  단순화 시킬 준비해라.  10개 초과  단순화 해라  하지만 절대적인 것이 아님.  특히 case마다 하나씩 세라는 것은 상황의존적인 부 분.
  • 32.
    THE SOFTWARE QUALITY LANDSCAPE 소프트웨어품질에 대한 조명 Chapter 20
  • 33.
  • 34.
    외부적 요소( 사용자중심 )  Correctness – 디자인에 부합한가  Usability – 배우고 사용하기 쉬운가  Efficiency – 효율적으로 실행되는가  Reliability – 요구사항에 맞게 동작하는가  Integrity – 결점 없이 동작하는가  Adaptability – 수정 없이 다양한 환경에서 실 행되는가  Accuracy – 정확한 결과를 도출하는가  Robustness – 시스템이 안 뻗는가.
  • 35.
    내부적 요소( 개발자중심 )  Maintainability – 얼마나 유지보수하기 좋은 가  Flxibility – 얼마나 확장하기 좋은가  Portability -얼마나 이식하기 좋은가  Reusability – 재사용성이 좋은가  Readability – 코드의 가독성이 좋은가  Testability – 테스트하기 좋은 구조인가  Understandability – 시스템의 구조를 이해하 기 쉬운가
  • 36.
    소프트웨어 품질의 특성 한 요소를 만족시키면  다른 요소도 같이 좋아진다  다른 요소가 나빠진다  다른 요소에 아무 지장이 없다  요소간의 이러한 상관관계를 기억하면 품질 목표를 정할 때 좋다.( Figure 20-1 )
  • 37.
  • 38.
    테크닉 1  소프트웨어품질 목표를 정하라  그렇지 않으면 프로그래머들이 서로 다른 품질 우선 순위를 갖고 코딩한다.  모든 목표를 만족시키는 것은 불가능하다.  품질 보장 활동을 명시하라  품질 보장 목표를 널리~널리~ 알리고 인지시켜라  안정성을 위해 테스트 전략을 잘 짜라  소프트웨어 엔지니어링 가이드라인을 잘 짜라  이 책도 하나의 가이드라인
  • 39.
    테크닉 2  비형식적인기술 리뷰를 해라  그냥 혼자 하는거  공식적 기술 리뷰를 해라  BVT 테스트( 품질 보장 허들 )  100%가 아닌 “충분한” 정도를 넘어야 함.  충분한 정도는 소프트웨어의 고유특성에 따라 다 름  외부 청중에게 리뷰 받아라.
  • 40.
    개발 절차  변화를컨트롤하는 처리절차  요구사항의 변화를 통제하지 못하면 디자인과 코드를 손상시킨다.  아키텍처의 변화  중간/최종 결과 평가  계획 진행 과정 평가  소프트웨어의 품질 요소 평가  개선과 재계획을 위해  프로토타이핑  핵심적 기능의 실현 가능성을 알아보기 위해
  • 41.
  • 42.
    결함 발견율  보통기업들  테스트 중심  결함 제거율 85%  선도 기업들  다양한 기술 조합  결함 제거율 95%  코드 읽기는 인터페이스 결함을 테스트는 로직 통제 결함을  Extreme Programming( table 20-3 )  최대 97%의 결함 제거율
  • 43.
    인스펙션(코드 리딩)과 테스팅 인스펙션이 테스팅보다  비용이 적다.  인스펙션은 1번만 보면 된다.  테스팅은 테스트, 결과 보기, 결함찾기까지 해야한다.  결함 발견 확률이 높다.  그래도 Best는? 다 하기  시스템의 중요한 부분에 있어 요구사항, 디자인, 아 키텍처 인스펙션하기.  모델링 혹은 프로토타이핑 해보기  인스펙션( 코드리딩 ) 하기  테스팅하기
  • 44.
  • 45.
    가능한 한 일찍! 소프트웨어 개발주기의 아래에서 위로 올라 가는 것은 비용이 훨씬 크다.  위에서 최대한 많은 결함을 확인하라.  요구사항, 아키텍처.
  • 46.
    소프트웨어 품질의 일반적인 원칙 생산성과 품질 향상은 다시 코딩하는 시간 을 최대한 줄이는 것.  그 원인이 요구사항의 변화든 디자인의 변화든 디버깅이든  개발에 있어 가장 많은 시간이 드는 것은 디 버깅과 리펙토링  총 개발 시간의 50%  이 시간을 줄이는 것이 소프트웨어 품질을 향상 시키는 핵심  즉 얼마나 적은 결함을 만드느냐
  • 47.
    요약  싸게 예방할것인가 비싸게 고칠 것인가  품질 목표를 정하고 널리~널리~ 알려라  결함 발견에 다양한 기술을 접목하라  결함은 가능한 한 일찍 발견하라
  • 48.
    끗~ Q &A 수고하셨습니다.