로버트 C.마틴의 '클린 코드'를 3장까지 읽고나서
이 책은 개발자들의 '필독서'라는 생각을 하게 되었다.
깃허브에서 잘 짜여진 소스코드와 내 소스코드를 비교해보며
어디서 차이가 발생하였는지 고민해본 경험이 있었다.
책을 읽고 답을 찾았다. 핵심은 '클린 코드'였다.
지금까지 공부한 지식을 개인적인 생각으로 녹여보고자 한다.
1. 클린코드란?
"유지보수가 쉬운 코드, 곧 읽기 좋은 코드"
클린 코드란 '가독성이 높으며, 직접적인 코드'이다. 책에선 다방면으로 이야기 하는데 생각을 정리하자면 이렇다.
제3자가 코드를 읽거나 수정하기 불편하다면 그건 '클린 코드'가 아니다.
int AB(int a, int b){
int c;
c = a + b ;
return c;
}
제3자가 코드를 읽거나 수정하기 쉬우면 그건 '클린 코드'다.
int getSum(int firstArg, int secondArg){
int sum = firstArg + secondArg;
return sum;
}
보다 싶이 클린 코드는 '길이'와 상관 없다.
제3자는 AB() 함수를 보고 당황을한다. 함수를 따라 들어가 보아야 동작을 이해할 수 있다.
getSum()은 이름만 보아도 해당 함수가 덧셈을 수행한다는 정보를 얻을 수 있다.
바로 이런 점에서 차이가 발생한다.
생각보다 클린 코드는 매우 중요하다. 우리는 혼자 일하지 않기 때문이다.
'클린 코드'를 적용하지 않으면 개발 속도는 빠를 수 있으나, 유지보수 시간이 길어진다.
적용하면 개발 속도는 더딜 수 있으나, 추후 90%를 차지할 유지보수 시간이 짧아진다.
어떤 것이 이익일지 우리는 바로 알 수 있다.
2. 구현 방법
"작은 노력에서 시작된다."
범위 : 네이밍 지정, 함수 작성
- 네이밍 - 변수나 함수명엔 의도를 보이자.
int w; //X html(); //X int weatherToday; //O getResponseBody(); //O
- 네이밍 - 길이와 상관없다. 명료하게 쓰자.
string m; //X string i; //X getRegistedUser(); //X string macAddr; //O string ipAddr; //O getUser(); //O
- 네이밍 - 타입이 이름에 꼭 들어갈 필요 없다.
int nDate; //X string sName; //X int date; //O string name; //O
- 네이밍 - 클래스명은 명사, 메서드명은 동사를 활용하자.
class User{ private: int age = 0; public: setAge(int age) //... }
- 네이밍 - 헷갈릴만한 단어는 빼고, 같은 단어는 통일해서 쓰자.
int l = 1; //X => 헷갈리는 변수명은 OUT! int O = 0; //X => 헷갈리는 변수명은 OUT! int x = 0; //X Master.printInfo(...); //X => Info와 Data 혼용 Slave.printData(...); //X => Info와 Data 혼용 int positionX = 3; //O Master.printInfo(...); //O Slave.printInfo(...); //O
- 함수 - 짧아야 한다.
string getIpAddr(char mac[MAC_LEN]){ //X string ip = ""; ... ARP arp = {}; arp.hardwareType = 0x0000 ... return ip } string getIpAddr(char mac[MAC_LEN]){ //O string ip = sendArp(mac); return ip; } ...
- 함수 - 하는 일은 하나다.
int isTmpFolder(string path){ ... checkPath(); //O => 함수는 본질의 단 하나 역할만 수행 setFlag(); //X writeFile(); //X ... }
- 함수 - 수준을 맞추자. 출력은 출력하는 곳에서..
class User{ private: int Age; public: int setAge(int age){ Age = age; std::cout << Age << std::endl; //X } int getAge(){ //O return Age; } }
- 함수 - 인자는 적을 수록 좋다.
int sendData(int mac[MAC_LEN], int ip[IP_LEN], char* dev, ...) // X int sendData(Packet packet); // O
- 함수 - 반복하지 마라.
int setPlace(Place place){ //X if(place.positionX == '1'){ place.positionY = '2'; place.positionX = '3'; }else if(place.positionX == '3'){ place.positionY = '2'; place.positionX = '3'; } } int setPlace(Place place){ //O if(place.positionX == '1' || place.positionX == '3') setPosition(2,3) }
3. 마치며
"좋은 그림과 나쁜 그림은 누구든 구별할 수 있다.
그러나 직접 그려보지 않으면 좋은 그림을 그리진 못한다."
어쩌면 그냥 무시하고 지나갈 수 있는 이론이나, 한번 적용해보면 추후 코드를 다시 볼 때 크게 와닿을 것이다.
본인도 아직 부족해 계속해서 공부해나가고자 한다. 저자는 이론만으론 클린코드를 작성할 수 없다고 말한다.
우리는 계속해서 작성했던 코드를 보완하고, 보완해나가야 한다.
글을 읽는 것에서 끝나지 않고, 본인의 코드를 찾아 변수명을 바꿔보는 작은 행동에서 큰 변화는 시작될 것이라 믿는다.
아직 3장까지 밖에 읽지 못했지만 완독을 하고 다시 한번 정리해볼 계획이다.
+ 피드백 및 저작권에 대한 문의 시 즉시 수정할 예정이다.
'My > Study' 카테고리의 다른 글
[Forensic] NTFS 파일 시스템에서 파일 복구해보기 (2) | 2020.10.16 |
---|---|
[Network] WPA2 Cracking with Hashcat (0) | 2020.10.14 |
[네트워크] Suricata(수리카타) 공부 (0) | 2020.07.23 |
[Analysis] PE(Portable Executable) 파일 포맷 공부 (2) | 2020.06.13 |
[MYSQL] JOIN 조인(INNER, OUTER, CARTESIAN, SELF)공부 (0) | 2020.04.11 |