Skip to content

Latest commit

 

History

History
287 lines (177 loc) · 7.22 KB

클린코드(Clean Code) & 시큐어코딩(Secure Coding).md

File metadata and controls

287 lines (177 loc) · 7.22 KB

클린코드(Clean Code) & 시큐어코딩(Secure Coding)


전문가들이 표현한 '클린코드'

한 가지를 제대로 한다.

단순하고 직접적이다.

특정 목적을 달성하는 방법은 하나만 제공한다.

중복 줄이기, 표현력 높이기, 초반부터 간단한 추상화 고려하기 이 세가지가 비결

코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행하는 것


클린코드란?

코드를 작성하는 의도와 목적이 명확하며, 다른 사람이 쉽게 읽을 수 있어야 함

즉, 가독성이 좋아야 한다.


가독성을 높인다는 것은?

다른 사람이 코드를 봐도, 자유롭게 수정이 가능하고 버그를 찾고 변경된 내용이 어떻게 상호작용하는지 이해하는 시간을 최소화 시키는 것...


클린코드를 만들기 위한 규칙이 있다.


1.네이밍(Naming)

변수, 클래스, 메소드에 의도가 분명한 이름을 사용한다.

int elapsedTimeInDays;
int daysSinceCreation;
int fileAgeInDays;

잘못된 정보를 전달할 수 있는 이름을 사용하지 않는다.

범용적으로 사용되는 단어 사용X (aix, hp 등)

연속된 숫자나 불용어를 덧붙이는 방식은 피해야함


2.주석달기(Comment)

코드를 읽는 사람이 코드를 작성한 사람만큼 잘 이해할 수 있도록 도와야 함

주석은 반드시 달아야 할 이유가 있는 경우에만 작성하도록 한다.

즉, 코드를 빠르게 유추할 수 있는 내용에는 주석을 사용하지 않는 것이 좋다.

설명을 위한 설명은 달지 않는다.

// 주어진 'name'으로 노드를 찾거나 아니면 null을 반환한다.
// 만약 depth <= 0이면 'subtree'만 검색한다.
// 만약 depth == N 이면 N 레벨과 그 아래만 검색한다.
Node* FindNodeInSubtree(Node* subtree, string name, int depth);

3.꾸미기(Aesthetics)

보기좋게 배치하고 꾸민다. 보기 좋은 코드가 읽기도 좋다.

규칙적인 들여쓰기와 줄바꿈으로 가독성을 향상시키자

일관성있고 간결한 패턴을 적용해 줄바꿈한다.

메소드를 이용해 불규칙한 중복 코드를 제거한다.


클래스 전체를 하나의 그룹이라고 생각하지 말고, 그 안에서도 여러 그룹으로 나누는 것이 읽기에 좋다.


4.흐름제어 만들기(Making control flow easy to read)

  • 왼쪽에는 변수를, 오른쪽에는 상수를 두고 비교

    if(length >= 10)
    
    while(bytes_received < bytest_expected)

  • 부정이 아닌 긍정을 다루자

    if( a == b ) { // a!=b는 부정
    	// same
    } else {
    	// different
    }

  • if/else를 사용하며, 삼항 연산자는 매우 간단한 경우만 사용

  • do/while 루프는 피하자


5.착한 함수(Function)

함수는 가급적 작게, 한번에 하나의 작업만 수행하도록 작성


온라인 투표로 예를 들어보자

사용자가 추천을 하거나, 이미 선택한 추천을 변경하기 위해 버튼을 누르면 vote_change(old_vote, new_vote) 함수를 호출한다고 가정해보자

var vote_changed = function (old_vote, new_vote) {
    
	var score = get_score();
    
	if (new_vote !== old_vote) {
		if (new_vote == 'Up') {
			score += (old_vote === 'Down' ? 2 : 1);
		} else if (new_vote == 'Down') {
			score -= (old_vote === 'Up' ? 2 : 1);
		} else if (new_vote == '') {
			score += (old_vote === 'Up' ? -1 : 1);
		}
	}
	set_score(score);
    
};

총점을 변경해주는 한 가지 역할을 하는 함수같지만, 두가지 일을 하고 있다.

  • old_vote와 new_vote의 상태에 따른 score 계산
  • 총점을 계산

별도로 함수로 분리하여 가독성을 향상시키자

var vote_value = function (vote) {
    
    if(vote === 'Up') {
        return +1;
    }
    if(vote === 'Down') {
        return -1;
    }
    return 0;
    
};

var vote_changed = function (old_vote, new_vote) {
    
    var score = get_score();
    
    score -= vote_value(old_vote); // 이전 값 제거
    score += vote_value(new_vote); // 새로운 값 더함
    set_score(score);
};

훨씬 깔끔한 코드가 되었다!



코드리뷰 & 리팩토링

레거시 코드(테스트가 불가능하거나 어려운 코드)를 클린 코드로 만드는 방법


코드리뷰를 통해 냄새나는 코드를 발견하면, 리팩토링을 통해 점진적으로 개선해나간다.


코드 인스펙션(code inspection)

작성한 개발 소스 코드를 분석하여 개발 표준에 위배되었거나 잘못 작성된 부분을 수정하는 작업


절차 과정
  1. Planning : 계획 수립
  2. Overview : 교육과 역할 정의
  3. Preparation : 인스펙션을 위한 인터뷰, 산출물, 도구 준비
  4. Meeting : 검토 회의로 각자 역할을 맡아 임무 수행
  5. Rework : 발견한 결함을 수정하고 재검토 필요한지 여부 결정
  6. Follow-up : 보고된 결함 및 이슈가 수정되었는지 확인하고 시정조치 이행

리팩토링

냄새나는 코드를 점진적으로 반복 수행되는 과정을 통해 코드를 조금씩 개선해나가는 것


리팩토링 대상
  • 메소드 정리 : 그룹으로 묶을 수 있는 코드, 수식을 메소드로 변경함
  • 객체 간의 기능 이동 : 메소드 기능에 따른 위치 변경, 클래스 기능을 명확히 구분
  • 데이터 구성 : 캡슐화 기법을 적용해 데이터 접근 관리
  • 조건문 단순화 : 조건 논리를 단순하고 명확하게 작성
  • 메소드 호출 단순화 : 메소드 이름이나 목적이 맞지 않을 때 변경
  • 클래스 및 메소드 일반화 : 동일 기능 메소드가 여러개 있으면 수퍼클래스로 이동

리팩토링 진행 방법

아키텍처 관점 시작 → 디자인 패턴 적용 → 단계적으로 하위 기능에 대한 변경으로 진행

의도하지 않은 기능 변경이나 버그 발생 대비해 회귀테스트 진행

이클립스와 같은 IDE 도구로 이용


시큐어 코딩

안전한 소프트웨어를 개발하기 위해, 소스코드 등에 존재할 수 있는 잠재적인 보안약점을 제거하는 것


보안 약점을 노려 발생하는 사고사례들
  • SQL 인젝션 취약점으로 개인유출 사고 발생
  • URL 파라미터 조작 개인정보 노출
  • 무작위 대입공격 기프트카드 정보 유출

SQL 인젝션 예시
  • 안전하지 않은 코드
String query "SELECT * FROM users WHERE userid = '" + userid + "'" + "AND password = '" + password + "'";

Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);

  • 안전한 코드
String query = "SELECT * FROM users WHERE userid = ? AND password = ?";

PrepareStatement stmt = connection.prepareStatement(query);
stmt.setString(1, userid);
stmt.setString(2, password);
ResultSet rs = stmt.executeQuery();

적절한 검증 작업이 수행되어야 안전함


입력받는 값의 변수를 $ 대신 #을 사용하면서 바인딩 처리로 시큐어 코딩이 가능하다.