아 더럽다... 내 코드 진짜 더러워.... 어떻게 하지?
마감일에 쫓겨서 코드를 만든 후 시간을 갖고서 내 코드를 들여다보면 이보다 더 더러울 수가 없다.
같은 기능을 동작하는 코드가 여러군데에 분포되어 있고, 한 함수에 왜 이렇게 많은 기능을 때려넣은거냐
이제 가급적 그러지 말자!
DRY (Don't Repeat Yourself)
- 특정한 지식, 의도, 로직, 비즈니스 등이 다양한 곳에서 다양한 형태로 계속 반복되는 것을 피하자의 원칙
- 시스템 내 특정 지식과 로직은 단 한 곳에서 명확하고 신뢰성 있게 나타나야 한다.
- 여러 모듈에 걸쳐 동일한 로직을 반복적으로 작성할 경우 로직의 변경사항이 발생할 경우 반복적 업데이트 뿐 아니라 실수가 잦아 유지보수의 악몽이 나타난다.
- 재사용성이 높기에 유지보수성도 높다.
- 이것과 상반되는 개념으로는
WET(Write Every Time)
이 있다.- 매번 작성하고 시간 낭비가 심하다.
KISS (Keep It Simple, Studpid)
- 심플하고 멍청하게 유지하자
- 대부분의 시스템은 복잡하기보다 심플하게 만들어졌을 때 잘 동작한다. 불필요한 복잡성은 피해야 한다.
- 코드를 작성할 때 10줄짜리를 1줄로 바꾸기 위해 화려한 테크닉을 이용하여 가독성을 떨어뜨리기 보다 심플하고 간결하게 작성하는 것이 좋다.
- 별도의 주석을 작성하지 않아도 함수 이름, 매개변수, 구현된 사항의 코드를 읽었을 때 한번에 이해되도록 한 가지의 기능을 수행하는 함수를 심플하게 작성하는 것이 좋다.
- 한 가지의 책임만 담당하는 클래스를 심플하게 만드는 것이 좋다.
- 사용자에게 보여지는 UI 담당 컴포넌트는 별도의 비즈니스 로직을 포함하지 않고 최대한 심플하고 멍청하게.. UI 관련 로직만 담당해야 한다.
- 서비스를 만들 때도 여러가지 기능을 복합적으로 담당하는 하나의 큰 서비스보단 하나의 기능을 담당하는 개별적인 심플한 서비스를 만드는 것이 좋다.
- 이를 통해 시스템을 심플.. KISS하게 만들 수 있다.
예시1
// KISS하지 않은 예시
function getFirst(array, isEven) {
return array.find(x => (isEven ? x % 2 === 0 : x % 2 !== 0));
}
// 위에보다는 KISS한 예시 (가독성 중시)
function getFirst(array, isEven){
if (isEven){
return array.find(x => x % 2 === 0);
} else {
return array.find(x => x % 2 !== 0);
}
}
- 하지만 함수에서 전달되는 인자의 값이 true인지 false인지에 따라 다른 동작을 하는 것은 simple하지 않다. 조금더 개선해보자면
// KISS한 예시
function getFirstOdd(array){
return array.find(x => x % 2 === 0);
}
function getFirstEven(array){
return array.find(x => x % 2 !== 0);
}
- 함수의 이름과 전달되는 매개변수를 이용하여 전달된 배열의 첫번째 짝수값을 리턴하는 함수임을 생각할 수 있다.
예시2
// KISS하지 않은 예시
function updateAndPrint(rawData) {
// prep data...
// more code...
db.update(rawData);
// get printer...
// more code ...
printer.print(data);
}
- 이름에서부터 이미 두 가지 기능 이상을 수행하므로 나쁘다. 함수 안에서 db를 업데이트하고 프린트하고 있으니...
// KISS한 예시
function update(rawData) {
// prep data...
db.update(rawData);
// more code...
return data;
}
function print(data) {
// get printer...
// more code...
printer.print(data);
}
- 원할 때 마다 업데이트와 프린트를 개별적으로 가능
YAGNI (You Ain't Gonna Need It)
- 개발할 때 필요하지 않은 기능, 당장 사용되지 않는 기능, 지나치게 미래 지향적인 기능(미래 확장성을 위해 이렇게 저렇게 사용해도 되도록)은 빼도록 하자
- 물론 현재 기능만 작성하도록 해선 안된다.
- 코드는 깨끗하고 변경이 쉽게, 유지보수도 용이하게.. 시스템에 불필요한 복잡성을 더하지 않는 내에서 확장성 있는 코드를 작성해야 한다.
- 딱! 필요한 기능만 염두하고 작성해야 한다.
예시
// YAGNI 하지 않은 예시
function deleteUser(id, softDelete = false) {
if (softDelete){
// don't delete from db but only mark as deleted.
return this._softDelete(id);
}
return db.removeById(id);
}
- 이렇게 필요햐지도 않은 softDelete를 도입하게 되면 기존에 작성해두었던 DB를 다루는 모든 곳에서 Update를 해주어야 한다.
- DB에는 여전히 삭제된 사용자의 데이터가 존재하고 단순히 지워졌다고 마크가 되어있기 때문에..
- DB에서 사용자를 읽어오는 모든 곳에서 'delete'마크의 여부를 확인하고 필터링해주어야 하기 때문이다.
- Git이 잘 발달했기 때문에 버전관리를 통해 쓰이지 않는 죽은 코드는 남겨두지 않고 깔끔하게 지우는 것이 좋다.
결론
시스템에서 YAGNI
를 통해 불필요한 요소를 제거하고 KISS
를 통해 심플함을 추가하자.
참고
반응형
'생각' 카테고리의 다른 글
10월의 목표 (0) | 2020.10.11 |
---|---|
[키보드 리뷰] 바밀로 va87m, 레오폴드 fc660c 비교 리뷰 (0) | 2020.02.28 |
깃헙블로그 만들기 어렵다.. (0) | 2019.07.26 |
초짜가 프로그래밍언어를 배운다는 것 (0) | 2019.07.14 |