일반적인 프로그래밍 원칙(JAVA)
By on August 1, 2019
Effective Java E/3 학습을 하며 정리 하는 글입니다.
-
지역변수를 최소화 하라.
- 지역변수의 유효 범위를 최소로 줄이면 코드 가독성과 유지보수성이 높아지고 오류 가능성은 낮아진다.
- 지역변수의 볌위를 줄이는 방법
- 가장 처음 쓰일 때 선언 하라.
- 선언과 동시에 초기화 하라.
- 메서드를 작게 유지하고 한 가지 기능에 집중 하라.
-
전통적인 for 문보다 for-each 문을 사용하라
for (Iterator<Element> i = c.iterator(); i.hasnext();){ Element e = i.next(); //e something }
for(int i =0; i < a.length; i++){ //a[i] something }
위 예제는 전통적인 for문을 이용 해서 컬렉션과 배열을 순회하는 코드이다. 이처럼 반복자와 인덱스 변수는 코드를 지저분하게 하고 오류가 생길 가능성이 생긴다.
for(Element e : elements){ //...e something }
for-each 문 예제
for-each 문은 명료하고, 유연하고, 버그를 예방해 주며 성능 저하도 없다. 가능한 곳에는 for-each 문을 이용 하자.
-
라이브러리를 익히고 사용하자.
초보 개발자 시절에 간단한 연산 기능을 만들기 위해 고민 해본적이 있다.
java.util.math 에 있는 기능 이였지만 몰랐기 때문이다.
아주 특별한 기능이 아니라면 라이브러리 형태로 구현 되어있을 가능성이 크다.
표준 라이브러리를 이용 하면 그 코드를 작성한 전문가의 지식과 앞서 검증된 기능을 활용 할 수 있기 때문에 안전하다.
자바의 방대한 라이브러리를 익히기에 무리가 있다면 적어도 java.lang, java.util, java.io 와 그 하위 패키지는 꼭 살펴보자.
또한 java.util.concurrent 의 동시성 기능도 알아두면 매우 도움이 된다. -
정확한 답이 필요하다면 float와 double은 피하라.
개발을 하면서 돈과 관련된 로직이 제일 머리가 아프다.. float와 double 타입은 과학과 공학 계산용으로 설계 되었다. 이진 부동소수점 연산에 쓰이며,
넓은 범위의 수를 빠르게 정밀한 ‘근사치’ 로 계산하도록 세심하게 설계 되어있으므로 정확한 금액이 필요한 경우에는 사용 하면 안된다.정확한 금액 계산을 위해서는 BigDecimal, int, long 타입을 사용하자. 단. BigDecimal 은 속도가 느리므로 주의하자.
-
박싱된 기본 타입 보다는 기본 타입을 사용하라.
자바의 데이터 타입 크게 기본 타입과 참조 타입으로 나뉜다. 기본타입은 int, double, boolean 등이 있고 참조 타입에는 String, List 이 있다.
기본타입에는 대응되는 참조 타입이 있다. 이를 박싱된 기본 타입이라고 한다.- 박싱된 기본 타입
- int -> Integer
- double -> Double
- boolean -> Boolean
오토박싱과 오토 언박싱 기능으로 인해서 구분 없이 사용 할 수는 있지만 둘은 차이가 있다.
- 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성이란 속성을 갖는다.
- 기본 타입의 값은 언제나 유효하나, 박싱된 기본 타입은 null을 가질 수 있다.
- 기본 타입이 박싱된 기본 타입보다 시간과 메모리 사용 면에서 효율적이다.
- 박싱된 기본 타입
-
다른 타입이 적절하다면 문자열 사용을 피하라.
- 문자열은 다른 값 타입을 대신하기에 적합하지 않다.
- 문자열(String) 대신 데이터가 수치형이라면 int, float, BigInteger를 사용 하고 데이터가 ‘예/아니오’ 질문의 답이라면 boolean 으로 변환해서 사용 하자.
- 문자열은 열거 타입을 대신하기에 적합하지 않다.
- 문자열은 혼합 타입을 대신하기에 적합하지 않다.
- 문자열은 권한을 표현하기에 적합하지 않다.
- 문자열은 다른 값 타입을 대신하기에 적합하지 않다.
-
문자열 연결은 느리니 주위하라.
String, StringBuilder, StringBuffer은 여러 포스트에서 다루었으니 참고 하자.
String 은 불변이므로 문자열(+) 를 하게 될 경우 양쪽 내용을 새로운 메모리에 복사해야 하므로 속도 저하가 발생한다.
문자열 처리를 위해서는 StringBuilder, StringBuffer을 사용 하고. StringJoining.class 을 활용하자. -
객체는 인터페이스를 사용해서 참조하라.
List<Book> books = new ArrayList<>();
List 인터페이스를 사용한 좋은 예
ArrayList<Book> books = new ArrayList<>();
ArrayList 클래스 타입을 이용한 나쁜 예
List 인터페이스를 사용한 예에서 ArrayList -> LinkedList 로 변경을 하기는 쉽다. 하지만 나쁜 예에서 변경하기는 어렵다.
이처럼 인터페이스를 타입으로 사용하는 습관을 길러 두면 프로그램이 훨씬 유연해진다. -
리플렉션보다는 인터페이스를 사용하라.
리플렉션 기능을 이용하면 임의의 클래스에 접근하여 Constructor, Method, Field 인스턴스를 가져올 수 있고,
인스턴스들로는 그 클래스의 멤버 이름, 필드 타입, 메서드 시그니처 등을 가져 올 수 있다. 복잡한 기능을 개발을 해야 할 경우 강력한 기능이지만, 단점이 많으므로 주의 하자. -
네이티브 메서드는 신중히 사용하라.
자바 네이티브 인터페이스(JNI)는 자바 프로그램이 네이티브 메서드를 호출 하는 기술이다. 네이티브 메서드란 C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 말한다. 어쩔수 없는 상황을 제외 하고는 사용 하는것에 한번더 신중히 생각 하라.
-
최적화는 신중히 하라.
성능을 높히려 최적화를 진행 하면 좋은 결과 보다는 해로운 결과가 생긴다. 빠른 프로그램 보다 좋은 프로그램을 작성하기 위해 노력 하면 성능을 따라 올 것이다.
-
일반적으로 통용되는 명명 규칙
자바 언어 명세[JLS, 6.1] 에 기술 되어있는 명세를 참조하자.
1) 철자 규칙
- 패키지 & 모듈 이름
- 각요소를 점(.) 으로 구분하여 계층적으로 짓는다.
- ex) com.google, java.util, org.eff
- 8자 이내의 짧은 단어를 선택 하자.
- ex) utilities(X), util(O)
- 각요소를 점(.) 으로 구분하여 계층적으로 짓는다.
- 클래스 & 인터페이스
- 하나이상의 단어로 이뤄지며, 각 단어는 대문자로 시작한다
- ex) String, Utils, Books
- 하나이상의 단어로 이뤄지며, 각 단어는 대문자로 시작한다
- 메서드 & 필드
- 하나이상의 단어로 이뤄지며, 각 단어는 소문자로 시작한다.
- ex) remove, get, set
- 하나이상의 단어로 이뤄지며, 각 단어는 소문자로 시작한다.
- 상수
- 모든 문자를 대문자로 쓰며 단어 사이는 밑줄로 구분한다.
- ex) VALUES, MIN_VALUE, MAX_VALUE
- 모든 문자를 대문자로 쓰며 단어 사이는 밑줄로 구분한다.
- 지역변수
- 변수가 사용되는 문맥에서 의미를 쉽게 유추할 수 있는 안에서 약어를 사용 해도 좋음
- ex) i, denin, houseNum
- 변수가 사용되는 문맥에서 의미를 쉽게 유추할 수 있는 안에서 약어를 사용 해도 좋음
- 타입 매개변수
- 타입 매개변수는 한문자로 표현한다.
- 임의의 타입 : T
- 컬랙션 원소 타입 : E
- 맵의 키와 값 : K, V
- 예외 : X
- 메서드 반환타입 : R
- 이외의 임의 타입 시퀀스 : T, U, V or T1, T2, T3
- 타입 매개변수는 한문자로 표현한다.
2) 문자 규칙
- 클래스는 단수 명사나 명사구를 사용
- ex) Thread, PriorityQueue, ChessPiece …..
- 객체를 생성 할 수 없는 클래스는 복수형 명사로 사용
- ex) Collectors, Collections ….
- 인터페이스 이름은 클래스와 동일하게 짓거나 able 혹은 ible로 끝나는 형용사로 짓는다.
- ex) Collection, Comparator, Runnable, Iterable, Accessible ….
- 애너테이션은 다양하게 활용 되며 특별한 규칙이 없다.
- ex) Singleton, ImplementedBy ….
- 메서드의 이름은 목적어를 포함한 동사나 동사 구로 짓는다.
- ex) append, drowImage …
- Boolean 값의 반환을 하는 메서드는 is 나 has로 짓는다.
- ex) isDigit, isEmpty …
- 인스턴스의 속성을 반환하는 메서드의 이름은 명사, 명사구, get으로 시작하는 동사구로 짓는다.
- ex) size, hashCode, getTime …
- 객체 타입의 변경 하는 메서드는 toType 형태로 짓는다.
- ex) toString, toInt ….
- 객체의 내용을 다른 뷰로 보여주는 메서드는 asType 형태로 짓는다.
- ex) asList…
- 객체의 값을 기본 타입 값으로 반환하는 메서드의 이름은 typeValue 형태로 짓는다.
- ex) intValue….
- 패키지 & 모듈 이름