빌 소러는 윤리적 관점에서 스스로 부끄러움을 느낀 코드에 대한 좋은 글을 미디엄(Medium)에 올린 적이 있다. 그러나 기술적인 측면에서도 소프트웨어를 부끄러워해야 이유는 많다. 부끄러워하지 않을 소프트웨어를 나타내는 11가지 단어를 살펴보자.
사용하는 언어 또는 기술 스택이 무엇이든 코드를 다음 단어로 설명할 수 있다면 좋은 코드일 가능성이 높다. 자신의 코드에 몇 개나 적용되는지 확인해 보라.
1. 디버그 가능(Debuggable)
대부분의 현대 런타임에서는 일종의 디버거를 연결할 수 있다. Node.js조차 비주얼 스튜디오로 디버그가 가능하다. 언젠가 무슨 일이 벌어지는지 알아내야 할 때 디버거를 연결해야 한다는 생각을 갖고 코드를 써야 한다.
그 의미를 정확히 설명하기는 어렵지만 이렇게 하면 때로는 데이터의 구조를 설계하는 데 영향을 미치기도 한다. 구조를 파나갈 필요가 없도록 더 많은 임시 변수를 사용할 수도 있다. 다행히 대부분은 결과적으로 좋은 습관이다.
가장 좋은 시작 방법은 문제가 없을 때 디버거 사용을 연습하는 것이다. 단계별로 진행하면서 할당을 살펴보고, 잘못된 값이 있을 경우 어떻게 할지 생각해 보라.
2. 로그 가능(Loggable)
런타임에 연결해서 코드를 단계별로 진행하기 위한 현대적 디버거가 있다 해도 세상은 그렇게 돌아가지 않는다. 즉, 코드가 실행되는 환경은 다양하다. 서버리스일 수도 있고 멀티스레드 환경이거나 분산 환경 또는 어딘가의 클라우드에서 실행되는 경우도 있을 것이다. 이러한 환경에서 코드는 개발자가 컴퓨터에서 실행할 때와 다르게 동작할지도 모른다.
따라서 로그가 필요하다. 그 말은 로깅 프레임워크가 필요하다는 의미다. 코드를 쓰고 로그를 읽을 수 있도록, 또는 최소한 일종의 로그 리더에서 소화가 가능하도록 로깅을 설정해야 한다. 소프트웨어에 로그 기능을 넣어야 한다.
이 부분을 못할 경우 프로덕션 배포에서 프로덕션 문제를 디버그하기 위해 로깅 코드를 배포하는 상황이 온다. 달리 말하자면 머리에 불이 붙은 채로 정유 공장으로 들어가는 격이다.
3. 테스트 가능(Testable)
이제는 단위 테스트를 써야 한다. 양보할 수 없는 경계선이다. “단위 테스트를 써야 할 비즈니스 케이스”를 논의하느라 발목을 잡는 회사에서 일한다면 떠나라. 그 논의 뒤에 따라오는 것은 혼돈의 지옥이다.
테스트 가능한 소프트웨어는 증명할 수 있는 간단한 작업을 수행하는 이해 가능한 함수로 분해된다. 테스트 가능한 소프트웨어는 더 효율적이고 탄력적이다.
테스트가 없는 레거시 코드가 있다면 그 코드를 수정하는 과정에서도 테스트를 작성하라. 가능하다면 테스트를 먼저 써라! 테스트 가능하게 만들기 위해 일부 구조를 변경해야 한다면 변경하라(조금씩이라도 해야 함).
4. 빠른 실패 가능(Fast-failable)
불안정한 코드의 가장 큰 경고 신호는 if (myvar == null) myvar ="";과 같은 코드 라인이다. 이 라인을 쓴 개발자는 간헐적 동작의 길로 개발자를 끌어내린다. 예측 가능하다는 면에서 차라리 지옥이 간헐적 행동의 영역보다 낫다. 간헐적 동작은 끊임없는 긴장감을 주다가 결국 모든 것이 눈앞에서 무너지는 그 특별한 순간(보통 비즈니스를 위해 매우 중요한 날, 또는 릴리스를 앞둔 새벽 2시)을 선사한다.
어떤 일이 “일어날 수 없다면” 일어나서는 안 된다. 일어난다면 코드는 확실한 오류 메시지를 보여주고 종료되어야 한다. 보기 좋지는 않지만 이는 문제가 해결되고 더 이상의 하향 문제를 유발하지 않음을 의미한다.
5. 멱등적(Idempotent)
특이한 이 단어는 “다시 할 때는 문제가 되지 않는다”는 의미다. 멱등적일 수 없는 요소도 있지만 가능한 모든 것은 멱등적이어야 한다. 멱등적이라는 것은, 예를 들어 거래 페이지를 새로 고친다고 해서(이전 페이지의 검증된 토큰이 있다는 이유만으로) 주문이 두 번 되는 경우가 없음을 의미한다. 대신 새로 고치면 주문 상태가 표시된다.
멱등적 동작이 코드 전반에 스며들어야 한다. 이는 디버거에서 라인 하나를 변경하고 이 변경이 문제를 수정하는지 여부를 확인할 때 디버거가 루틴의 시작으로 돌아가고 정상적으로 작동한다는 것을 의미한다. 이렇게 하면 데이터가 쉽사리 엉키지 않는 예측 가능한 소프트웨어를 만들 수 있다.
6. 불변적(Immutable)
기능적인 코드가 이를 위한 기반을 만들었다. 변수가 있으면 변수는 한 번 할당된 다음 새 데이터 구조로 결과를 변경한다. 기능적 코드를 쓰지 않더라도 불변성을 확보할 수 있다.
불변적 코드는 더 탄력적이고 온갖 종류의 쓰레드 문제를 피해간다. 불변적(또는 기능적 또는 객체 지향) 코드가 특수한 사례(예를 들어 저수준 인터프리터 작성)에 맞지 않는 저수준적 이유(디스패치의 수)가 있지만, 대다수 개발자가 쓰는 일반적인 비즈니스 코드에는 이러한 이유가 존재하지 않는다. (첫 I/O 호출보다 중요한 디스패치 최적화는 없다는 의미)
7. 이해 가능(Intelligible)
함수형 프로그래밍이 유행하자 사람들은 여기에 다소 과하게 몰입하면서 코드는 여전히 가독성이 있어야 한다는 사실을 망각했다. 10년 20년 전의 객체 지향 코드도 마찬가지다.
첫 번째 원칙 : 코드를 컴퓨터가 읽을 수 있게 만드는 것은 컴파일이다. 개발자가 할 일은 코드를 사람이 읽을 수 있게 작성하는 것이다.
8. 수정 가능(Modifiable)
얼마 전에 필자는 일부 코드에서(세션 컨텍스트에서 사용자 이름 포착) 극히 간단한 변경 작업을 하려고 했다. 애초에 이 코드가 작성된 방식 탓에 사용자 이름을 잡아서 필요한 곳으로 보내려면 많은 부분을 풀어서 수정해야 했다. 달리 말하자면 그 코드를 쓴 당사자를 제외하면 수정 가능성이 상당히 떨어지는 코드였다. 그 사람이 무슨 설계 원칙을 사용했든 문서화되지 않았고 다음에 그 코드를 물려받은 개발자가 쉽게 알아보고 이해할 수도 없다.
각 클래스, 모듈, 함수 등은 앞으로 어느 부분이든 바뀔 수 있다는 점을 염두에 두고 작성해야 한다. 데이터가 더 필요할 수도 있다(보안 정보 또는 컨텍스트). 무엇이든 항상 버전 2가 나온다는 점을 유념하고 코드를 작성하라.
객체 지향 코드에서 이는 방대한 상속 구조를 만들지 않음을 의미한다. 함수형 프로그래밍에서는 지나치게 세분화되지 않은 또는 컨텍스트가 있는 매개변수를 사용하는 함수를 설계하는 것을 의미한다.
9. 문서화 가능(Documentable)
좋은 코드는 그 자체가 문서라고 할 수 있다. 관건은 클래스, 함수, 변수의 명명이다. 또한 JavaDoc(또는 개발자가 사용하는 언어의 상응 개념)과 코드 설계 역시 중요하다.
“이것”과 “이것이 하는 일”을 문서화하기 위해 10가지 다른 부분을 참조해야만 한다면 그 설계는 다시 생각해야 한다.
10. 모듈형(Modular)
좋은 코드는 적어도 필요한 데이터를 공급하는 도구를 사용해서 독립적으로 실행 및 수정할 수 있는 논리적 부분으로 분할된다.
11. 빌드 가능(Buildable)
다른 개발자가 깃(Git)에서 코드를 받아 간단히 빌드를 실행할 수 없다면 그 빌드는 개선이 필요한 것이다. 물론 메이븐(Maven)이나 메이크(Make) 같은 “유명한” 빌드 툴이 필요한 정도까지는 괜찮다. 그러나 일주일, 몇 날 며칠 또는 몇 시간의 프로세스가 필요하다면 그 빌드는 고쳐야 한다.
새 팀원이 올 때, 개발자가 새 컴퓨터를 받을 때, 또는 중요한 핫픽스 릴리스 중에 매번 빌드와 씨름해야 한다면 이는 팀에 크나큰 부담이 될 것이다. editor@itworld.co.kr
Sponsored
Surfshark
“유료 VPN, 분명한 가치 있다” VPN 선택 가이드
ⓒ Surfshark VPN(가상 사설 네트워크, Virtual Private Network)은 인터넷 사용자에게 개인 정보 보호와 보안을 제공하는 중요한 도구로 널리 인정받고 있다. VPN은 공공 와이파이 환경에서도 데이터를 안전하게 전송할 수 있고, 개인 정보를 보호하는 데 도움을 준다. VPN 서비스의 수요가 증가하는 것도 같은 이유에서다. 동시에 유료와 무료 중 어떤 VPN을 선택해야 할지 많은 관심을 가지고 살펴보는 사용자가 많다. 가장 먼저 사용자의 관심을 끄는 것은 별도의 예산 부담이 없는 무료 VPN이지만, 그만큼의 한계도 있다. 무료 VPN, 정말 괜찮을까? 무료 VPN 서비스는 편리하고 경제적 부담도 없지만 고려할 점이 아예 없는 것은 아니다. 보안 우려 대부분의 무료 VPN 서비스는 유료 서비스에 비해 보안 수준이 낮을 수 있다. 일부 무료 VPN은 사용자 데이터를 수집해 광고주나 서드파티 업체에 판매하는 경우도 있다. 이러한 상황에서 개인 정보가 유출될 우려가 있다. 속도와 대역폭 제한 무료 VPN 서비스는 종종 속도와 대역폭에 제한을 생긴다. 따라서 사용자는 느린 인터넷 속도를 경험할 수 있으며, 높은 대역폭이 필요한 작업을 수행하는 데 제약을 받을 수 있다. 서비스 제한 무료 VPN 서비스는 종종 서버 위치가 적거나 특정 서비스 또는 웹사이트에 액세스하지 못하는 경우가 생긴다. 또한 사용자 수가 늘어나 서버 부하가 증가하면 서비스의 안정성이 저하될 수 있다. 광고 및 추적 위험 일부 무료 VPN은 광고를 삽입하거나 사용자의 온라인 활동을 추적하여 광고주에게 판매할 수 있다. 이 경우 사용자가 광고를 보아야 하거나 개인 정보를 노출해야 할 수도 있다. 제한된 기능 무료 VPN은 유료 버전에 비해 기능이 제한될 수 있다. 예를 들어, 특정 프로토콜이나 고급 보안 기능을 지원하지 않는 경우가 그렇다. 유료 VPN의 필요성 최근 유행하는 로맨스 스캠은 인터넷 사기의 일종으로, 온라인 데이트나 소셜 미디어를 통해 가짜 프로필을 만들어 상대를 속이는 행위다. 이러한 상황에서 VPN은 사용자가 안전한 연결을 유지하고 사기 행위를 방지하는 데 도움이 된다. VPN을 통해 사용자는 상대방의 신원을 확인하고 의심스러운 활동을 감지할 수 있다. 서프샤크 VPN은 구독 요금제 가입 후 7일간의 무료 체험을 제공하고 있다. ⓒ Surfshark 그 외에도 유료 VPN만의 강점을 적극 이용해야 하는 이유는 다음 3가지로 요약할 수 있다. 보안 강화 해외 여행객이 증가함에 따라 공공 와이파이를 사용하는 경우가 늘어나고 있다. 그러나 공공 와이파이는 보안이 취약해 개인 정보를 노출할 위험이 있다. 따라서 VPN을 사용하여 데이터를 암호화하고 개인 정보를 보호하는 것이 중요하다. 서프샤크 VPN은 사용자의 개인 정보를 안전하게 유지하고 해킹을 방지하는 데 유용하다. 개인정보 보호 인터넷 사용자의 검색 기록과 콘텐츠 소비 패턴은 플랫폼에 의해 추적될 수 있다. VPN을 사용하면 사용자의 IP 주소와 로그를 숨길 수 있으며, 개인 정보를 보호할 수 있다. 또한 VPN은 사용자의 위치를 숨기고 인터넷 활동을 익명으로 유지하는 데 도움이 된다. 지역 제한 해제 해외 여행 중에도 한국에서 송금이 필요한 경우가 생길 수 있다. 그러나 IP가 해외 주소이므로 은행 앱에 접근하는 것이 제한될 수 있다. VPN을 사용하면 지역 제한을 해제해 해외에서도 한국 인터넷 서비스를 이용할 수 있다. 따라서 해외에서도 안전하고 편리하게 인터넷을 이용할 수 있다. 빠르고 안전한 유료 VPN, 서프샤크 VPN ⓒ Surfshark 뛰어난 보안 서프샤크 VPN은 강력한 암호화 기술을 사용하여 사용자의 인터넷 연결을 안전하게 보호한다. 이는 사용자의 개인 정보와 데이터를 보호하고 외부 공격으로부터 사용자를 보호하는 데 도움이 된다. 다양한 서버 위치 서프샤크 VPN은 전 세계 곳곳에 여러 서버가 위치하고 있어, 사용자가 지역 제한된 콘텐츠에 액세스할 수 있다. 해외에서도 로컬 콘텐츠에 손쉽게 접근할 수 있음은 물론이다. 속도와 대역폭 서프샤크 VPN은 빠른 속도와 무제한 대역폭을 제공하여 사용자가 원활한 인터넷 경험을 누릴 수 있도록 지원한다. 온라인 게임, 스트리밍, 다운로드 등 대역폭이 필요한 활동에 이상적이다. 다양한 플랫폼 지원 서프샤크 VPN은 다양한 플랫폼 및 디바이스에서 사용할 수 있다. 윈도우, 맥OS, iOS, 안드로이드 등 다양한 운영체제 및 디바이스에서 호환되어 사용자가 어디서나 안전한 인터넷을 즐길 수 있다. 디바이스 무제한 연결 서프샤크 VPN은 무제한 연결을 제공하여 사용자가 필요할 때 언제든지 디바이스의 갯수에 상관없이 VPN을 사용할 수 있다.