클린코드 / 리팩토링 / 시큐어 코딩

이유석·2022년 5월 11일
0
post-thumbnail

클린코드

정의

  • 코드를 작성하는 의도와 목적이 명확하며, 다른 사람이 쉽게 읽을 수 있어야 한다.
  • 가독성이 높은 코드

가독성을 높이려면 다음과 같이 구현해야 한다.

  • 네이밍이 잘 되어야 함
  • 오류가 없어야 함
  • 중복이 없어야 함
  • 의존성을 최대한 줄여야 함
  • 클래스 혹은 메소드가 한 가지 일만 처리해야 함

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

1. Naming (네이밍)

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

int elaspsedTimeInDays;
int daysSinceCreation;
int fileAgeInDays;

잘못된 정보를 전달할 수 있는 이름은 사용하지 않는다.
범용적으로 사용되는 단어 사용 X
연속된 숫자나 불용어를 덧붙이는 방식은 피해야 한다.

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) {...}
  • 부정이 아닌, 긍정을 다루자
if ( a == b) { // a != b 는 부정
	// same
} else {
	// different
}
  • if/else 를 사용하며, 삼항 연산자는 매우 간단한 경우만 사용한다.

  • do/while 루프의 사용은 가급적 피하자.

5. Function (착한 함수)

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

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

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

이전 코드

public void vote_changed (String old_vote, String new_vote) {
	int 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);
}

해당 함수는 2가지 작업을 수행하고 있다.

  • old_vote와 new_vote의 상태에 따른 score 계산
  • 총점을 계산 - set_score();

별도의 함수로 분리하여 가독성을 향상시켜 보자.

public int vote_value (String vote) {
	
    if (vote == "Up") {
    	return 1;
    } else if (vote == "Down") {
    	return -1;
    }
    return 0;
}


public void vote_changed (String old_vote, String new_vote) {
	int score = get_score();
    
    score -= vote_value(old_vote); // 이전 값 제거
    score += vote_value(new_vote); // 새로운 값 갱신
    
	set_score(score);
}

리팩토링

정의

  • 프로그램의 외부 동작은 그대로 둔 채, 내부의 코드를 정리하면서 개선하는 것

  • 레거시 코드(테스트가 불가능하거나 이해하기 어려운 코드)를 클린 코드로 만드는 것

  • 리팩토링 작업은 코드의 가독성을 높이고, 향후 이루어질 유지보수에 큰 도움이 된다.

리팩토링이 필요한 코드는?

  • 메소드 정리 : 그룹으로 묶을 수 있는 코드, 수식을 메소드로 변경함

  • 객체 간의 기능 이동 : 메소드 기능에 따른 위치 변경, 클래스 기능을 명확히 구분

  • 데이터 구성 : 캡슐화 기법을 적용해 데이터 접근 관리

  • 조건문 단순화 : 조건 논리를 단순하고 명확하게 작성

  • 메소드 호출 단순화 : 메소드 이름이나 목적이 맞지 않을 때 변경

  • 클래스 및 메소드 일반화 : 동일 기능 메소드가 여러개 있으면 수퍼클래스로 이동

목적

  • 소프트웨어를 더 이해하기 쉽고, 수정하기 쉽게 만드는 것
  • 즉 개발 속도를 향상시켜준다.

리팩토링 진행 방법

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

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

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


클린코드와 리팩토링의 차이

리팩토링이 더 큰 의미를 갖는다.
클린코드 : 단순히 가독성을 높이기 위한 작업
리팩토링 : 클린코드를 포함한 유지보수를 위한 코드 개선의 작업이다.

클린코드와 같은 부분은 설계부터 잘 이루어져 있는 것이 중요하고,
리팩토링은 결과물이 나온 이후 수정이나 추가 작업이 진행될 때 개선해나가는 것이 올바른 방향이다.


시큐어 코딩

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

보안 약점을 노려 발생하는 사고사례들

  • SQL 인젝션 취약점으로 개인유출 사고 발생

  • URL 파라미터 조작 개인정보 노출

  • 무작위 대입공격 기프트카드 정보 유출

profile
https://github.com/yuseogi0218

0개의 댓글