Karen
15k
2016-03-10 10:57:32
8
5259

정개발의 "no more agile" - 9. 모던 자바의 역습(3) 자바 코딩 스타일 변천사




정개발의 "no more agile"

9. 모던 자바의 역습(3) 자바 코딩 스타일 변천사



  이번 포스팅은 김대우 님(http://lekdw.blogspot.kr/  )과 함께 진행한 동명의 웨비너의 발표 내용에 바탕을 두고 작성되었습니다. 세상에 나온지 어느덧 20년. 오랜동안 프로그래밍 언어의 절대 강자로서 세상을 호령하던 자바를 둘러싼 진실 혹은 거짓말 그리고 과거와 미래에 대하여 알아봅니다.



  스크롤의 압박을 피하기 위해 이번 포스팅은 다섯 파트로 나누어 연재합니다.

  1. 프로그래밍 언어 자바
  2. 자바를 둘러싼 진실 혹은 거짓말
  3. 자바 코딩 스타일 변천사
  4. 모던 자바의 등장 - Java8
  5. 섹시한 자바 개발자로 거듭나기



모던 자바의 역습

(3) 자바 코딩 스타일 변천사



  자바는 20년이나 되는 역사속에서 꾸준히 발전을 거듭해온 만큼, 언어 사양 자체의 변화에 따른 코딩 스타일의 변화를 겪어왔습니다. 구식 코딩 스타일은 당장 프로그램을 작동시키는 데에는 큰 문제가 없어보이나, 가독성을 떨어트리거나 어떤 경우에는 버그의 원인이 되기도 하는 등, 품질 저하의 요인으로 작용합니다. 때문에 코딩 규약 등에 포함시켜 프로젝트나 프로덕트 전체의 코딩 스타일을 최신 스타일로 유지할 필요가 있습니다. 


  이번 장에서는 아직까지도 쉽게 접할 수 있는 구식 코딩 스타일의 잔재를 확인하고, 최신 코딩 스타일을 적용시키는 방법에 대해서 살펴보도록 하겠습니다.


파일을 행 단위로 읽어 리스트에 저장하는 간단한 프로그램을 예로 들어보겠습니다.

출처: http://www.slideshare.net/shintanimoto/from-old-java-to-modern-java


C 스타일 자바private List m_list=null; // null 초기화private int read_file(String str_le_name){ // 스네이크 케이스로 메소드명을 작성    String str_line; // 지역 변수를 함수 맨 윗부분에 몰아서 정의하고 있음    List list_lines=new ArrayList();    int i_result // 함수의 처리 결과를 숫자로 반환        =read_le(str_le_name,list_lines); // 결과값을 참조에 의한 호출을 이용해 넘겨줌      if(i_result==0){ //        List list_record=new ArrayList();        for(int i=0;i<list_lines.size();i++){            str_line=(String)list_lines.get(i);            Record record=new Record();            i_result=parse_line(str_line,record); // 결과값을 참조에 의한 호출을 이용해 넘겨줌            if(i_result!=0){                return i_result; //하위함수의 결과값이 0(정상종료)이 아닐경우 이를 그대로 반환            }            list_recordord.add(record);        }        m_list=list_record;        return 0; //정상 종료 시 0 반환    }else{        return i_result;    }}


  C 스타일의 자바 코드는 자바 초창기에 흔히 보였지만 오늘날에도 원래 C 언어에서 넘어온 개발자들이 흔히 고수하는 스타일이기도 합니다. 구조적 프로그래밍 패러다임이 녹아 있는 C 스타일의 자바 코드는, 가독성을 크게 해칠 뿐만 아니라 객체지향적 디자인 품질도 저하시키기 때문에, 자바 코딩 스타일로서는 매우 좋지 않은 형태라 할 수 있습니다.



자바1.4 스타일
private List resultList;private List readFile(String leName) throws SystemException { //예외를 이용한 에러 처리    List lines = readFile(fileName);    List recordList = new ArrayList();    for (int i = 0; i < lines.size(); i++) {        String line = (String) lines.get(i);        Record record = parseLine(line);        recordList.add(record);    }    return recordList; //값을 반환}


  자바 1.4 스타일은 지금까지도 흔히 쓰일 정도로 가장 오랫동안 자바 코딩의 표준 스타일로 자리 잡았던 코드 스타일입니다. 방금 전에 살펴보았던 C 스타일 코드와 비교해 보았을 때 가장 큰 차이점은, 에러 처리에 있어서 결과값이 아닌 예외를 사용한다는 점입니다. 결과값 또한 처리 결과 얻어진 데이터를 반환하고 있으며, 참조에 의한 호출은 사용하지 않게 된 점을 볼 수 있습니다. 이 밖에 메소드명이나 변수명에 스네이크 케이스대신, 단어의 첫 글자에 대문자를 사용하여 가독성을 높인 낙타표기법을 이용하는 것도 중요한 포인트입니다.



자바 7 스타일
private List<Record> readFile(String leName)throws SystemException {    List<String> lines = readFile(fileName); //제네릭을 이용한 형 지정.    List<Record> recordList = new ArrayList();    for (String line : lines) {        Record record = parseLine(line);        recordList.add(record);    }    return recordList;}


  자바 7의 경우 제네릭과 foreach가 적용되어 코드가 좀 더 심플해진 것을 알 수 있습니다. 




  try-with-resources

  자바 7에 도입된 문법 중 아직도 많은 자바 프로그래머에게 생소한 try-with-resources에 대해서 간단히 살펴보겠습니다.


  방금 전 살펴 보았던 파일 읽기 예제에 예외 처리를 추가하여 보겠습니다.


private List<String> readFile(String leName) {    List<String> lines = new ArrayList<String>();    BufferedReader reader = null;    try {        reader = new BufferedReader(new FileReader(fileName));        String line;        while ((line = reader.readLine()) != null) {            lines.add(line);        }    } catch (FileNotFoundException ex) {        throw new SystemException(FILE_NOT_FOUND, ex);    } catch (IOException ex) {        throw new SystemException(FILE_READ_ERROR, ex);    }    nally {        try {            if (reader != null) {                reader.close();            }        } catch (IOException ex) {            // 이건 무시?        }    }    return lines;}


  자바 개발자라면 io 예외에 대해 어디까지 처리해 줘야 하는지 한 번쯤은 고민해 봤을 것 입니다. 자바 7의 경우 try-with-resources 구문을 통해 이러한 딜레마를 간단히 해결할 수 있습니다.


private List<String> readFile(String leName) {    List<String> lines = new ArrayList<>();    try (FileReader in = new FileReader(fileName);            BufferedReader reader = new BufferedReader(in)) {        String line;        while ((line = reader.readLine()) != null) {            lines.add(line);        }    } catch (FileNotFoundException ex) {        throw new SystemException(FILE_NOT_FOUND, ex);    } catch (IOException ex) {        throw new SystemException(FILE_READ_ERROR, ex);    }    return lines;}



  위의 예제처럼 파일을 읽어들여 리스트 형태로 반환하는 것뿐이라면 자바 7의 NIO2에 새로 추가된 API인  File.readAllLines를 이용해 다음과 같이 간단히 처리할 수도 있습니다.


private List<String> readFile(String leName) {    try {        return Files.readAllLines(Paths.get(fileName), Charset.defaultCharset());    } catch (IOException ex) {        throw new SystemException(FILE_READ_ERROR, ex);    }}




  새로운 코딩 스타일에 적응하기

  사용하는 언어의 새 버전이 등장할 때마다 기대감에 설레이기도 하지만, 한편으로는 새 스타일에 적응하는 것에 대한 부담감이 있는 것 또한 사실입니다. 필자의 경우 새 코딩 스타일에 적응하는 방법으로 다음과 같은 원칙을 세워놓고 있습니다.


  • 프로젝트 도중에는 언어의 버전이 바뀐다 하더라도 특별한 경우가 아닌 이상 코딩 표준은 변경하지 않는다.
  • 새로운 코딩 스타일의 적용은 개개인이 실시하는 것이 아닌 코딩 표준(coding conventions)에 먼저 적용한 후에, 팀이나 프로젝트 전체에 일괄적으로 적용시킨다.
  • 코딩 스타일의 준수 여부는 가급적 Checkstyle이나 SonarQube와 같은 정적 해석툴을 이용해 기계적으로 실시할 수 있도록 하며, 정적 해석툴이 지원하지 못하는 범위는 코드 리뷰를 통해 준수 여부를 확인한다.




칼럼 출처
http://www.moreagile.net/2015/12/modernjava3.html



♣에디터 : 정개발님께서 작년 12월 10일에 올리신 글입니다 :) 언어가 변하고 패션이 변하듯, Java의 코딩 스타일도 변해왔네요^^

0
  • 댓글 8

  • bluerain
    2k
    2016-03-10 11:04:48

    원문도 소스쪽이 줄바꿈이 안되어 있어서 보기가 힘드네요


  • 개발하는가수
    32
    2016-03-10 18:03:30
    좀 보고싶은데 ㅠㅠ 개행이 안되어있어요 ㅠㅠ.. 방법없나요?
  • 난리닷
    761
    2016-03-10 18:46:51

    Try with resource 는 처음 보는거네요^^ 

    언제나 감사드립니다 

    Java 8에 람다식도 배우고 싶은데..

    생각보다 많이 변해서 어렵더라구요ㅜㅜ


  • 아야나미
    2k
    2016-03-10 23:55:01

    좋은글 감사합니다.

    foreach를 사용해야하는데 제네릭있는 리스트임에도 기존 int i를 자꾸 사용하게됩니다 ㅜ.ㅜ

  • 새우드릴
    522
    2016-03-11 09:57:49


    C 스타일 자바
    private List m_list=null; // null 초기화
    private int read_file(String str_file_name){ // 스네이크 케이스로 메소드명을 작성     
    	String str_line; // 지역 변수를 함수 맨 윗부분에 몰아서 정의하고 있음    
    	List list_lines=new ArrayList();    
    	int i_result // 함수의 처리 결과를 숫자로 반환        
    	=read_file(str_file_name,list_lines); // 결과값을 참조에 의한 호출을 이용해 넘겨줌      
    	
    	if(i_result==0){ //        
    	List list_record=new ArrayList();        
    	
    	for(int i=0;i<list_lines.size();i++){            
    		str_line=(String)list_lines.get(i);            
    		Record record=new Record();            
    		i_result=parse_line(str_line,record); // 결과값을 참조에 의한 호출을 이용해 넘겨줌             
    		
    		if(i_result!=0){               
    			return i_result; //하위함수의 결과값이 0(정상종료)이 아닐경우 이를 그대로 반환            
    		}            
    		list_recordord.add(record);        
    	}        
    	m_list=list_record;        
    	return 0; //정상 종료 시 0 반환    
    	}else{
    		return i_result;    
    	}
    }
    
    
    
    자바1.4 스타일
    private List resultList;
    private List readFile(String fileName) throws SystemException { //예외를 이용한 에러 처리    
    	List lines = readFile(fileName);    
    	List recordList = new ArrayList();    
    	
    	for (int i = 0; i < lines.size(); i++) {        
    		String line = (String) lines.get(i);        
    		Record record = parseLine(line);        
    		recordList.add(record);    
    	}    
    	return recordList; //값을 반환
    }
    
    
    
    
    
    
    자바 7 스타일
    private List<Record> readFile(String fileName)throws SystemException {    
    	List<String> lines = readFile(fileName); //제네릭을 이용한 형 지정.     
    	List<Record> recordList = new ArrayList();    
    	
    	for (String line : lines) {        
    		Record record = parseLine(line);        
    		recordList.add(record);    
    	}    
    	return recordList;
    }



    메모장 열고 개행처리 했습니다.

    귀찮으신분들 보시기 편하라고 올린건데 문제가 된다면 삭제하겠습니다.


  • 오로롱이
    1k
    2016-03-11 15:41:16

    죄송합니다 agile을 abigaile 로 봤습니다.

  • fender
    26k
    2016-03-12 09:08:15
    아마도 'readFile(fileName)'는 'readLines(fileName)'의 오타인 것 같습니다.
  • jcpark1220
    55
    2016-04-04 18:21:30

    저는 1.7 스타일을 코딩을 알고있음에도 불구하고 1.4스타일로 코딩중인 ㅠㅠ

  • 로그인을 하시면 댓글을 등록할 수 있습니다.