Java 로 풀어보는 알고리즘입니다. 📖
코딩테스트를 대비하여 JAVA1.8 부터 제공되는 함수형 API 는 사용하지 않았습니다.

문제 : https://www.algospot.com/judge/problem/read/HELLOWORLD

 

algospot.com :: HELLOWORLD

Hello World! 문제 정보 문제 예의 바른 프로그래머들은 인사를 잘 합니다. 프로그래밍 언어를 배우면서 처음으로 짜는 프로그램이 항상 Hello World! 인 것만 봐도 알 수 있지요. AOJ 의 첫 문제에서도

www.algospot.com


풀이입니다. 🤔

1
2
3
4
5
6
7
8
9
import java.util.*;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int cases = scanner.nextInt();
        while (cases-- > 0System.out.printf("Hello, %s!\n", scanner.next());
    }
}
cs

 

 


이 포스트를 읽어주셔서 감사합니다. 🙇🏻‍♂️

반응형

'개발이야기 > 알고스팟' 카테고리의 다른 글

[ENCRYPT] 문자열 암호화  (0) 2021.12.27
[LECTURE] Lecture Note  (0) 2021.12.27
[DRAWRECT] 사각형 그리기  (0) 2021.12.27
[ENDIANS] Endians  (0) 2021.12.27
[MERCY] Merciful Algospot  (0) 2021.12.27
Posted by N'

소프트웨어에서 이름은 어디에서든 사용합니다.

변수에도 이름을 붙이고, 함수, 인수, 클래스, 패키지 등에 이름을 붙입니다. 또한, 파일, 디렉터리, war, jar 등 여기저기 이름을 많이 붙이네요. 


이렇듯 이름을 짓는 일은 많으며, 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 더 많습니다. 

좋은 이름을 지으면, 자신을 포함해 코드를 읽는 사람이 행복해 집니다.


이번 포스팅에서는 이름 잘 짓는 몇 개의 규칙에 대해 다뤄보려 합니다.


1. 의도를 분명히 밝혀라.


많은 개발자들이 "의도가 분명하게 이름을 지으라" 는 이야기를 많이 합니다.

의도가 분명한 이름은 정말로 중요합니다.


변수나 함수 클래스 이름은 다음과 같은 굵직한 질문에 모두 답해야 합니다.


- 왜 존재해야 하나?


- 수행 기능은?


- 사용 방법은?


따로 주석이 필요하다면, 의도를 제대로 나타내지 못함을 의미합니다.



1
int d;  // 경과 시간 (단위: 날짜)
cs


이름 d 는 아무 의미도 드러나지 않습니다. 해당 변수가 표현하는 논리적인 이름이 필요합니다.

아래처럼 말이죠.


1
int daysInAppraisalDeadline; 
cs



의도가 드러나는 이름을 사용하면, 코드 이해와 변경이 쉬워집니다.

한번, 다음 함수를 주목해주세요.


1
2
3
4
5
6
7
8
9
10
11
public List<int[]> getThem() {
    ArrayList<int[]> list = new ArrayList<>();
        
    for (int[] n : theList) {
        if (n[0== 4) {
            list.add(n);
        }
    }
 
    return list;
}
cs


함수 function 은 복잡한 문장은 없어 보입니다. 하지만, 무슨 일을 하는지 짐작하기 어렵습니다. 


문제는 코드의 단순함이 아닌 함축성에 있습니다. 코드 맥락이 명시적으로 드러나지 않습니다.

위에서 제공하는 코드는 아래와 같은 질문을 남깁니다.


1. theList 에 무엇이 들어있는가?


2. theList 에서 0번째 값이 어째서 중요한가?


3. 값 4는 무엇인가?


4. 함수가 반환하는 list 는 어떻게 사용되는가?


코드만 보고는 위 질문에 대한 답을 알 수 없습니다. 

하지만, 다음과 같이 코드를 변경하면 어떨까요? 아래 코드는 단순함에 변화를 주지 않고, 이름만 변경했습니다.


1
2
3
4
5
6
7
8
9
10
11
public List<int[]> getFlaggedCellS() {
    ArrayList<int[]> flaggedCellS = new ArrayList<>();
 
    for (int[] cell : gameBoard) {
        if (cell[STATUS_VALUE] == FLAGGED) {
            flaggedCellS.add(cell);
        }
    }
 
    return flaggedCellS;
}
cs


이 코드를 보고, 위의 질문에 답을 해 볼 수 있습니다.


1. theList 에 무엇이 들어있는가?

    -> gameBoard 로 변경되면서, 게임판임을 알 수 있습니다.


2. theList 에서 0번째 값이 어째서 중요한가?

    -> 0 은 STATUS_VALUE 라는 값을 통해, 셀의 상태를 의미함을 알 수 있습니다.


3. 값 4는 무엇인가?

-> 4라는 상수에 FLAGGED 라는 이름을 붙임으로, 플래그가 된 상태임을 알 수 있습니다.


4. 함수가 반환하는 list 는 어떻게 사용되는가?

-> 반환하는 list 에 flaggedCellS 라는 이름을 붙임으로, 플래그 된 셀 목록을 구한다는 것을 알 수 있습니다.


각 개념에 이와 같이 이름만 붙여도 충분히 나아진 것을 알 수 있습니다. 

단순함은 변하지 않았지만, 코드는 더욱 명확해졌습니다.


조금 더 리팩토링을 해볼 수 있을 것 같습니다. 

int 배열 사용 대신 Cell 이라는 클래스를 만들고, Cell::isFlagged 라는 메소드를 사용하여 FLAGGED 라는 상수를 감춰도 좋을 것 같습니다.


1
2
3
4
5
6
7
8
9
10
11
public List<Cell> getFlaggedCellS() {
    ArrayList<Cell> flaggedCellS = new ArrayList<>();
 
    for (Cell cell : gameBoard) {
        if (cell.isFlagged) {
            flaggedCellS.add(cell);
        }
    }
 
    return flaggedCellS;
}
cs



2. 그릇된 정보를 피하라.


프로그래머는 코드에 그릇된 정보를 남기면 안됩니다.

그릇된 단서는 코드의 의미를 흐리기 때문이죠.


예를들어, 우리는 resumeList, appraisalList 와 같이 목록을 나타내는 변수명을 짓습니다.

프로그래머에게 있어 List 는 자료구조를 나타내는 특수한 의미이며, 해당 변수들이 List가 아니라면, 그릇된 정보를 제공하는 셈입니다.

간단하게 resumeS(s가 눈에 안뛸 수도 있기 때문에 대문자로 강조..), appraisalGroup 등으로 명명하는 것을 책에서는 추천하고 있습니다.


또한, 서로 흡사한 이름을 쓰지 않도록 주의할 것을 말합니다.

한 모듈에서는 getStringForHandlingOfResume 라 하고, 다른 곳에서 getStringForStorageOfResume  라 하면 두 모듈의 차이를 알 수 없습니다.


조금은 유머같지만, 알파벳 l, o 들의 문자들은 지양하는 것이 좋습니다.


1
2
3
4
5
int i = l;
int x = 1;
        
int f = o;
int fx = 0;
cs


폰트나 IDE 에 따라, 위의 코드는 헷갈릴 수 있습니다.



3. 의미 있게 구분하라.


종종, 어떤 코드들은 이름에 연속된 숫자나 불용어(의미없는 글자)를 추가하는 경우가 있습니다.

이런 코드들은 모듈의 가독성을 꽤 나쁘게 만듭니다.


예를들어, 한번 아래 메소드 서명을 볼 수 있습니다. 

연속적인 숫자를 덧붙인 이름(a1,a2... aN) 은 그릇된 정보를 제공하지도, 어떤 의도도 주지 못하는 이름입니다.


1
public void copyPropertise(Object a1, Object a2)
cs


위의 서명을 source, destination 등 의미있는 이름을 사용하는 것으로도, 충분히 어떻게 사용하면 되는지 나타낼 수 있습니다. 


1
public void copyPropertise(Object source, Object destination);
cs


불용어를 사용하는 경우 역시, 어떤 정보를 주지 못하며 혼란을 줄 수 있습니다.

Product 라는 클래스가 있고 ProuductInfo, ProductData 라 부른다면, info 나 data 는 의미없는 정보입니다.

a, an, the 등의 접두어 역시 불용어입니다.

그렇다고, 접두어나 접미어의 사용이 나쁘다는 것이 아닙니다. product 라는 이름이 있다고, theProduct 라는 이름을 짓지 말자는 것입니다.


변수 이름에 variable 을 쓰거나, 테이블에 table 이라는 단어 역시 마찬가지로 불용어 입니다.

name 과 nameString 은 다를 것이 없습니다. name 이 숫자가 될 일은 없을테니까요...



4. 인터페이스와 구현 클래스


예를들어, 커피를 제작하는 Abstract Factory를 구현한다고 가정해보죠.


이 절과 관련은 없지만, Abstract Factory 가 무엇인지 궁금하다면, 이 곳을 참고! :-)



이 패턴에 따라 클래스를 그려보면, 인터페이스와 구현체로 나눠 제작하게 될 것입니다.

이 때, 인터페이스의 이름을 어떻게 할까요? ICoffeeFactory? CoffeeFactory? 


책의 저자는 옛날 코드에서 많이 보이는 인터페이스에 붙이는 접두어(I)에 대하여, (잘해봤자) 주의를 흐트리고, (나쁘게는) 과도한 정보를 제공한다고 주장합니다.

굳이 다루는 클래스가 인터페이스라는 사실을 알리고 싶지 않고, 사용자는 CoffeeFactory 라고만 생각하면 좋겠다고 합니다.

책의 저자는 차라리 CoffeeFactoryImp 가 ICoffeeFactory 보단 좋다고 말합니다.



5. 클래스 이름


클래스 이름과 객체 이름은 명사나 명사구가 적합합니다.

Resume, Account 등이 좋은 예입니다. Data, Info 등과 같은 단어는 피하고 동사는 사용하지 않습니다.



6. 메소드 이름


메소드 이름은 동사나 동사구가 적합합니다. 

postPayment, save, deletePage 등이 적합하며, javabean 규칙에 따라 접근자(getXXX), 변경자(setXXX), 조건자(isXXX) 를 사용하길 권장합니다.


생성자 같은 경우는 중복정의를 하기 보단 팩토리 메소드를 사용하길 권장합니다.

팩토리 메소드는 직접적으로 생성자를 이용하지 않고, 어떤 상태를 가진 객체를 생성하는 것을 의미합니다.


예를들어, 중복정의된 생성자 보단,


1
Complex fulcrumPoint = new Complex(23.0);
cs


아래와 같이, 의미를 가진 이름으로 표현된 팩토리 메소드를 이용하는 것이 좋습니다.


1
Complex fulcrumPoint = Complex.FromRealNumber(23.0);
cs



7. 한 개념에 한 단어를 사용하라.


추상적인 개념 하나에 단어 하나를 선택하고 이를 고수하기를 권장합니다.


예를들어, 똑같은 일을 수행하는 접근자 메소드를 클래스마다 get, fetch 등 제작기 부르면 혼란스러워 집니다.

메소드 이름은 독자적이고 일관적이어야 합니다. 그래야 주석을 뒤져보지 않고 프로그래머가 올바른 메소드를 선택할 수 있습니다.


마찬가지로 동일 코드 기반에서 controller, manager, driver 를 섞어쓰는 것을 지양합니다.

DeviceManager 와 DeviceController 는 근본적으로 다를까요? 둘 다 Controller 가 아닐지? 혹은 둘 다 Manager 가 아닐까요? 

이름이 다르면 독자는 당연히 클래스도 다르고 타입도 다르다고 생각할 것입니다.



8. 해법 영역에서 가져온 이름을 사용하라.


코드를 읽는 사람 역시도 프로그래머입니다. 그렇기 때문에 전산용어, 패턴명, 알고리즘 명 등은 써도 무방합니다.

Factory 패턴에 익숙한 개발자는 CoffeeFactory 를 금방 이해하며, JobQueue 역시 특정 일을 하는 큐임을 인지할 수 있습니다.



9. 문제 영역에서 가져온 이름을 사용하라.


문제 영역에서 가져온 이름을 사용하면, 해당 분야의 전문가에게 의미를 물어 문제를 이해할 수 있습니다.

문제 영역의 개념과 깊은 문제를 해결하는 코드라면, 문제 영역에서 이름을 가져와야 합니다.



10. 의미있는 맥락을 추가하라.


스스로 의미가 분명한 이름이 없진 않습니다. 

하지만 대다수 이름은 분명하지 못하며, 클래스, 함수 등에 공간을 넣어 맥락을 부여합니다.

모든 방법이 실패한다면, 마지막 수단으로 접두어를 사용합니다.


예를들어, 아래 코드를 확인해봅시다.


1
2
3
4
5
6
7
8
public class TestClass {
 
    String firstName, lastName, streetName, city, state, zipCode;
 
    public static void main(String[] args) {
 
    }
}
cs


변수 명을 본다면, 해당 변수들이 주소를 나타낸다는 것을 알 수 있습니다.

하지만 어떤 메소드가 오직 state 하나만 사용한다면, 그 메소드만 보고 주소라는 사실을 바로 알긴 쉽지 않을 것 같아 보입니다.


그래서 다음과 같이 addr 이라는 접두어를 사용하여, addrState 라 하면 조금 더 의미가 명백해집니다. 


1
2
3
4
5
6
7
8
9
10
11
12
public class TestClass {
 
    String addrFirstName, addrLastName, addrStreetName, addrCity, addrState, addrZipCode;
 
    public static void main(String[] args) {
 
    }
 
    public String getAddrState() {
        return addrState;
    }
}
cs


하지만, Address 라는 클래스를 제작한다면 변수가 조금 더 큰 개념에 속한다는 것이 컴파일러에게도 명백해집니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
 * 주소 클래스
 *
 * Created by Doohyun on 2018. 1. 7..
 */
public class Address {
    String firstName;
    String lastName;
    String streetName;
    String city;
    String state;
    String zipCode;
}
 
cs



11. 불필요한 맥락을 없애라.


사내에서 개발한 InJob 이라는 어플리케이션이 있었습니다.

저는 이 프로젝트에서 모든 유틸 클래스 및 기본이 되는 클래스들에 INJOB 이라는 접두어를 붙인 적이 있었습니다.


아래와 같이 말이죠...


1
2
3
4
5
6
7
8
/**
 * inJob 에서 구현된 리소스 유틸
 *
 * Created by Doohyun on 2018. 1. 7..
 */
public class InJobResourceUtil {
    private InJobResourceUtil() {}
}
cs


어차피, InJob 이라는 안드로이드 프로젝트에서만 독릭접으로 사용될 코드이며, 이 클래스의 명은 ResourceUtil 로 변경하는 것이 옳다고 생각합니다.


비슷하지만, 조금은 다른 케이스로는 다음과 같은 사례를 볼 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 * inJob 에서 사용하는 코드 정의
 *
 * Created by Doohyun on 2018. 1. 7..
 */
public class InJobCodeDefinition {
 
    public static class APPLICATION_TYPE {
        public static final String APP = "INJOB_APPLICATION_TYPE_APP";
        public static final String WEB = "INJOB_APPLICATION_TYPE_WEB";
    }
}
 
cs


위와 같은 경우 코드 클래스 자체가 다른 응용에서 사용할 수 있기 때문에, InJobCodeDefinition 이라는 이름을 사용하고 있습니다.

또한 코드의 value 역시 다른 솔루션과 구분을 짓기 위해 "INJOB_APPLICATION_TYPE_APP" 을 사용하지만, 클래스와 상수명에는 접두어가 없고 계층적인 구조를 사용하고 있습니다.

개념적으로 불필요한 맥락과 필요한 맥락을 나누고, 개념에 속하도록 제작이 된 좋은 사례인 듯 합니다. :-)



책의 저자는 위와 같은 규칙을 소개하며, 마치면서 다음과 같은 말을 했습니다.


사람들은 이름을 바꾸지 않으려는 이유는 다른 개발자가 반대할까 두려워서다. 

여느 코드 개선 노력과 마찬가지로 이름 역시 나름대로 바꿨다가는 누군가 지책할지도 모른다. 

그렇다고 코드를 개선하려는 노력을 중단해서는 안 된다.


이 문구를 읽었을 때, 3년차가 되면서 협업이라는 그늘 안에서 보수적이라는 두려움을 외면 시 했던 된 저를 보게 되었습니다.

남들이 안좋게 작성했기 때문에, 어쩔 수 없다는 핑계로 안좋은 코드를 이어갔었던 듯 합니다.


더불어 제가 코드를 작성하는 안좋은 버릇이 충분히 이 절에서 꽤 많이 보였습니다. 하하...

충분히 반성을 하게 된 포스팅인 듯 합니다.


이 글이 저처럼 조금 더 여러분들이 나아지는 것에 도움이 되었으면 좋겠습니다.


Clean Code 클린 코드
국내도서
저자 : 로버트 C. 마틴(Robert C. Martin) / 박재호,이해영역
출판 : 인사이트 2013.12.24
상세보기



반응형

'개발이야기 > Clean Code' 카테고리의 다른 글

깨끗한 코드  (1) 2018.01.07
[프롤로그] Clean Code  (0) 2018.01.05
Posted by N'

Clean Code 의 첫 도입부는 책 이름답게 "깨끗한 코드" 라는 주제를 다루고 있습니다.

첫번째 장에서는 깨끗한 코드의 중요성과 유명하고 노련한 프로그래머들이 생각하는 깨끗한 코드에 대한 생각들이 담겨 있었습니다.

이번 포스팅에선, 위 내용에 대한 주관적인 요약을 다뤄보려 합니다.



1. 코드가 존재하리라.


최근 프로그램을 제작하기 위한 많은 기술들이 등장하고 있으며, 아마 프로그램을 제작하는 방법은 점점 편리해졌습니다.

제작하는 방법이 쉬워지는 만큼, 개발자들은 코드보단 요구사항에 조금 더 집중해야한다고 생각하는 의견들도 많이 있습니다.

생각해보면, 새로 등장하는 많은 언어들은 어렵거나 귀찮은 내용을 점점 추상화하고 있습니다.

(어느덧 C++ 이후 부터의 언어는 포인터를 찾아볼 수 없고, 병렬 처리같은 복잡한 수준의 구현은 함수형 등으로 쉽게 나타낼 수도 있습니다.)


이러한 구현과정의 추상화는 계속될 것이며, 우리는 요구사항에 조금 더 집중할 수 있을 것입니다. 

그렇지만 요구사항을 나타내는 구체적인 방법은 결국 코드이며, 코드는 계속 우리 곁에 남아있을 것입니다.



2. 나쁜 코드


협업을 하게 되면, 동료들의 많은 코드를 볼 수 있습니다. 

또한, 이 코드를 사용하거나 고쳐야할 상황도 많으며 종종 누군가가 작성했던 나쁜 코드들에게 시달렸을 것입니다.

(아마 종종 누구가는 자신일 확률이 높을 수도 있습니다. ㅡㅡ^)


나쁜 코드는 당연한 이야기이지만 개발 속도를 크게 떨어트립니다. 

간단한 변경이란 없고, 코드를 변경할 시 여기저기서 문제가 발생할 것입니다. 

이러한 일들은 팀 생산력을 크게 저하시킬 것입니다.


생산력을 올리고자, 새로 인원을 충원해도 그들은 설계의도를 모르기 때문에 더 나쁜 코드가 생산될 수 있죠.

덕분에 생산력은 0를 향해 내려갈 것입니다.



 

이 상황이 계속되면, 개발자들은 재설계를 요구할 수 밖에 없습니다. 

모듈 하나 추가할 때마다 너무 많은 시간이 들며, 이곳 저곳 버그가 많다면 계속 헝겊을 짜집는 것보다는 새로 만들기를 희망합니다.

관리자들 역시 재설계에 자원을 쏟기 싫지만, 생산성이 0이기에 어쩔 수 없이 허락을 할 것입니다.


이제, 개발자들은 두 팀으로 나눠집니다. 

기존 시스템을 유지할 인력과 새로 재개발을 할 타이거 팀으로 말이죠. 

타이거 팀은 기존 시스템을 대체할 새 시스템을 내놓아야 합니다. 또한 기존 시스템에 추가되는 변경점도 따라잡아야 하죠.

이 상태는 오랫동안 이어질 수 있습니다. 

오랫동안 이어진다면 기존 타이거팀은 모두 떠났고, 또 다른 인력이 새 시스템을 설계 하겠다고 할 것입니다. 

(현재 시스템 역시 엉망이기 때문이겠죠..)


위의 이야기는 책에 등장하는 경험담이며, 현재 제가 재직하고 있는 회사에서도 겪고 있습니다...  ㅜㅡㅜ

깨끗한 코드를 만드는 노력은 비용 절감뿐 아니라, 전문가로써 살아남는 방법이라 주장하고 있습니다.



3. 태도


나쁜 코드가 심각한 장애물이라는 것은 개발자라면 많이 공감을 할 것입니다.

왜 우리들의 코드는 이렇게 되었을까요?


요구사항이 원래 설계를 뒤집는 방향으로 변해서? 일정이 촉박해서? 멍청한 관리자와 조급한 기획자 때문에?

이 책에서는 이러한 잘못은 모두 프로그래머에게 있다고 합니다.


관리자와 기획자는 우리에게 현실성을 자문하고, 도움을 요청합니다. 

우리에게 정보를 구하지 않더라도, 우리는 적극적으로 그들에게 정보를 제공해야 합니다.

우리는 프로젝트에 가장 깊게 관여하고 있으며, 프로젝트 실패는 우리에게 커다란 책임이 있습니다. 나쁜코드가 초래하는 실패라면 더더욱 책임이 큽니다.


"아니, 잠깐만요.. 상사가 시키는 대로 하지 않으면 짤린다구요!" 우리의 의견은 보통 이럴 텐데 말이죠..

하지만, 대다수의 관리자들은 진실을 원하며, 일정에 쫓기더라도 좋은 코드를 원합니다. 

관리자들이 일정을 밀어붙이는 것은 그들의 책임이며, 좋은 코드를 사수해야하는 것은 우리들의 일입니다.


이 책에서는 한가지 비유를 했습니다.


자신이 의사라 가정하자. 

어느 환자가 수술전에 손을 씻지 말라고 요구한다. 시간이 너무 오래걸리니깐?

하지만, 의사는 단호하게 거부한다. 왜? 질병과 감염의 위험은 환자보다는 의사가 잘 아니까. 

환자 말을 그대로 따르는 행동(범죄일 뿐만 아니라)은 전문가 답지 못하다.


개발자 역시, 나쁜코드의 위험을 이해하지 못하는 관리자 말을 그대로 따르는 것은 전문가 답지 못할 것입니다.



4. 깨끗한 코드란?


나쁜 코드는 이와 같이 나쁘며, 빨리 가려면 깨끗한 코드를 유지해야 한다고 인정해야 한다고 가정합시다.

그렇다면, 깨끗한 코드는 어떻게 작성할까요?


이 책에서는 깨끗한 코드를 구현하는 행위는 그림을 그리는 것과 같다고 비유합니다.

대부분의 사람들은 그림이 잘그렸는지 엉망인지 알고 있습니다. 

하지만, 그림을 구분하는 능력이 그림을 잘 그리는 능력은 아닙니다


깨끗한 코드를 작성하려면 '청결' 이라는 어렵게 습득한 코드감각을 활용해 자잘한 기법을 이용하는 절제와 규율이 필요합니다. 나쁜 모듈을 보면 좋은 모듈로 개선할 방안을 떠올리며, 최고 방안을 선택한 후 여기서 거기까지 이동하는 경로를 세웁니다.


즉, 깨끗한 코드를 작성하려면 코드 감각을 익혀야 하며 그 전에 깨끗함이 무엇인지 알 필요가 있습니다.


깨끗한 코드의 정의는 매우 다양합니다. 프로그래머 수만큼 말이죠..

그래서, 이 책에서는 유명하고 노련한 프로그래머들이 말하는 깨끗한 코드에 대한 의견을 소개했습니다.


이번 절에서는 이 의견들 중 인상깊은 내용에 대한 소개를 하고자 합니다.


- 깨끗한 코드는 잘 읽혀야 한다.


많은 의견 중 공통적인 가장 첫번째 의견은 잘 읽히는 코드여야 한다고 합니다.

잘 읽히는 코드는 우아하며, 보기에 즐거워야 합니다. 

잘 쓴 문장처럼 잘 읽히며, 설계자의 의도를 숨기지 않습니다. 추측이 아닌 사실에 근거해야 하며, 필요한 내용만 담아야 합니다.

또한, 표현력 역시 명확해야 할 것입니다. (이름짓기 등..)


이와 같이 깨끗한 문장은 작성자와 구독자 모두 읽기 쉬워야 하며, 고치기도 쉬워야 합니다.



- 깨끗한 코드는 한가지 일을 제대로 한다.


수많은 소프트웨어 원칙은 이 간단한 교훈 하나로 귀결됩니다.

나쁜 코드는 너무 많은 일을 하려 애쓰다가 의도가 뒤섞이고 목적이 흐려집니다. 


깨끗한 코드는 한가지에 '집중'하며, 각 함수, 클래스, 모듈은 주변 상황에 현혹되거나 오염되지 않은 채 한 길만 걷는다고 합니다.


'메소드 추출' 과 같은 리팩토링은 이 교훈을 따르기 위한 방법입니다.




- 깨끗한 코드는 짐작했던 기능을 그대로 수행한다.


이 내용은 매우 당연하지만, 심오한 내용입니다. 

하지만, 짐작했던 그대로 수행하는 모듈은 생각보다 많지 않을 것입니다. 

(헷갈리고, 모듈끼리 복잡하게 엉켜있고, 또는 엉뚱한 기능도 수행하고.. ㅜㅡㅜ)


깨끗한 코드는 읽으면서 놀랄 일이 없어야 합니다. 

각 모듈은 다음 무대를 준비하며, 다음에 벌어질 상황이 보여야 합니다. 

즉, 코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 된다고 합니다.



실제 책의 내용에는 조금 더 공감되고 좋은 내용이 더 있었습니다.

하지만, 모든 내용은 결국 모듈을 한 가지 일만 하도록 최대한 작게 구현하며, 의도를 잘 표현할 수 있도록 세심한 주의 할 것을 말합니다.


지막으로 한가지 생각해 볼 것은 코드를 잘짜는 것이 전부가 아니라는 것입니다. 

시간이 지나도 언제나 깨끗함을 유지하는 것이 더 중요한 듯 합니다.


'소프트웨어 장인정신' 에서도 언급하는 보이스카우트 규칙은 이 내용을 말하고 있습니다.


"캠프장은 처음 왔을 때보다 더 깨끗하게 해놓고 떠나라!"


시간이 지날수록 코드가 좋아지는 프로젝트에서 작업한다면 얼마나 좋을까요? 

사실 전문가라면, 너무도 당연한 이야기입니다.


'지속적인 개선이야말로 장인 정신의 본질'이라는 저자의 말을 남기며, 이번 포스팅을 마칩니다.


Clean Code 클린 코드
국내도서
저자 : 로버트 C. 마틴(Robert C. Martin) / 박재호,이해영역
출판 : 인사이트 2013.12.24
상세보기














반응형

'개발이야기 > Clean Code' 카테고리의 다른 글

의미 있는 이름  (6) 2018.01.07
[프롤로그] Clean Code  (0) 2018.01.05
Posted by N'