Effective Java 3/E - (9) 일반적인 프로그래밍 원칙

신복호·2020년 12월 6일
0

Effactive JAVA 3/E

목록 보기
9/12
post-thumbnail

9장 일반적인 프로그래밍 원칙

아이템 57. 지역변수 범위를 최소화해라

  • 지역변수의 범위를 줄이는 가장 강력한 기법은 역시 "가장 처음 쓰일 때 선언하기"다.

  • 거의 모든 지역변수 선언과 동시에 초기화해야한다.

    • try-catch 문 제외
      • 변수를 초기화하는 표현식에서 검사 예외를 던질 가능성이 있다면 try문 안에서 초기화를 하는 것이 좋다.
  • 메소드를 작게 유지하고 한가지 기능에 집중하는 것이 좋다.

아이템 58. 전통적인 for문 보다는 for-each 문을 사용해라

  • 기존 for문
List<Integer>  list = searchService.getList();
for(int i =0 ; i < list.size(); i++) {
	
}
  • for-each : 향상된 for문 / 반복자와 인덱스 변수를 사용하지 않아 소스가 깔끔해진다. / 하나의 관용구로 컬렉션과 배열을 모두 처리할수 있다.
// 생략
List<Integer>  list = searchService.getList();
for(Integer number : list){

}...
  • for-each를 사용하지 말아야 하는경우

    • 파괴적인 필터링 - 컬렉션을 순회하면서 선택된 원소를 제거해야 한다변 반드시 remove 메소드를 호출해야 한다. java 8 부터는 Collection의 removeIF 메소드를 사용해 컬렉션을 명시적으로 순회하는 일을 피할 수 있다.

    • 변형 - 리스트나 배열을 순회 하면서 그 원소의 값 일부 혹은 전체를 교체해야하는 경우 리스트의 반복자나 배열의 인덱스를 사용해야 한다.

    • 병렬 반복 - 여러 컬랙션을 병렬로 순회해야 한다면 각각의 반복자와 인덱스 변수를 사용해 엄격하고 명시적으로 제어해야 한다.

전통적인 for문과 비교 했을때 for-each문은 명료하고, 유연하고, 버그를 예방한다. 예외적인 사항을 제외하곤 for-each문을 사용하자.

아이템 59. 라이브러리를 익히고 사용해라

  • 아주 특별한 나만의 기능이 아니라면 누군가 이미 라이브러리 형태로 구현해놨을 가능성이 크다.

  • 표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 여러분보다 앞서 사용한 다른 프로그래머들의 경험들을 활용하수 있다.

  • 공개된 라이브러리를 사용하는 것이 코드 품질과 안정성을 높일수 있다.

아주 특별한 나만의 기능이 아니라면 누군가 이미 라이브러리 형태로 구현해놓았을 가능성이 크다. 즉 라이브러리 코드는 개발자 각자가 작성하는 것보다 주목을 훨씬 많이 받으므로 코드의 품질도 그만큼 높아진다.

아이템 60. 정확한 답이 필요하다면 float와 Double을 피하자

  • 정확한 계산이 필요하다면 float나 double을 피하자(특히 금융관련 계산과는 맞지 않는다.)

  • 금융 계산에서는 BigDecimal , int, Long을 사용하는것이 좋다.

  • 소수점 추적은 시스템 상에 맡기고, 코딩 시 불편함이나 성능저하를 신경쓰지 않겠다면 BigDecimal을 사용하자

아이템 61. 박싱된 기본 타입보다는 기본 타입을 사용하자

  • 기본형 : int, double, boolean <-> 박싱된 기본 타입 : Integer, Double, Boolean

  • 기본형과 박싱된 기본형 타입의 차이

    • 첫번째: 기본형은 값만 가지고 있으나 박스된 기본형 타입은 값에 식별성이란 속성이 포함된다.

    • 두번째 : 기본형 타입의 값은 언제나 유효하나, 박싱된 기본 타입은 유효하지 않는 NULL을 가질수 있다.

    • 세번째 : 기본형 타입이 박싱된 기본 타입보다 시간과 메모리 사용면에서 더 효율적이다.

  • 박싱형 기본 타입은 기본형과 혼용하면 언박싱이 되고 그 과정에서 nullPointerException이 발생 할수 있다.

아이템 62. 다른 타입이 적절하다면 문자열 사용을 피해라

  • 문자열은 다른 값 타입, 열거 타입, 혼합 타입을 대신하기에 적합하지 않다.

  • 문자열은 권한을 표현하기에 적합하지 않다.

  • 더 적합한 데이터 타입이 있거나 새로이 작성할 수 있다면 문자열을 쓰고 싶은 유혹들을 뿌리쳐라

아이템 63. 문자열 연결은 느리니 주의해라

  • 문자열 연결 연산자로 문자열 N개를 연결하는 시간은 n^2에 비례한다.

  • 성능을 포기 하고 싶지 않다면 String 보다는 StringBuilder를 사용하는 것이 좋다. (StringBuildr.append 사용 추천)

아이템 64. 객체는 인터페이스를 사용해 참조해라

  • 적합한 인터페이스가 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하는 것을 추천한다.
// 좋은예, 인터페이스를 타입으로 사용했다.
Set<Son> sonSet = new LinkedHashSet<>();

// 나쁜예, 클래스를 타입으로 사용했다.
LinkedHashSet sonSet = new LinkedHashSet<>();
  • 인터페이스를 타입으로 상용하는 습관을 길러두면 프로그램이 훨씬 유연해진다.

  • 적합한 인터페이스가 없다면 당연히 클래스로 참조해야 한다.

  • 적합한 인터페이스가 없다면 클래스의 계층구조 중 필요한 기능을 만족하는 가장 덜 구체적인 (상위의) 클래스 타입으로 사용하자.

아이템 65. 리플렉션보다는 인터페이스를 사용하자

Reflection?

리플렉션이란 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법을 말한다. 투영, 반사 라는 사전적인 의미를 지니고 있다.

출처: https://gyrfalcon.tistory.com/entry/Java-Reflection [Minsub's Blog]

-> 프로그램에서 임의의 클래스에 접근할수 있도록 하는 기능이다.

  • Reflection 단점

    • 컴파일타임 검사가 주는 이점을 하나도 누릴수 없다.

    • 리플렉션을 이용하면 코드가 지저분하고 장황해진다.

    • 성능이 떨어진다.

  • 리플렉션은 아주 제한된 형태로만 사용해야 그 단점을 피하고 이점만 취할수 있다.

  • 리플렉션은 인스턴스 생성에만 쓰고, 이렇게 만든 인스턴스는 인터페이스나 상위 클래스로 참조해 사용하자

2020년 12월 6일 작성할 당시에는 이해되지 않는 부분

리플랙션은 복잡한 특수 시스템을 개발할 때 필요한 강력한 기능이지만 단점도 많다.

아이템 66. 네이티브 메소드는 신중하게 사용하자

자바 네이티브 인터페이스(JNI)

자바 프로그램이 네이티브 메소드를 호출하는 기술이다.
(c,c++ 과 같이 네이티브 프로그래밍 언어로 작성한 메소드)

  • 네이티브 메소드의 주요 쓰임 3가지

    • 레지스트리 같은 플랫폼 특화 기능을 사용
    • 네이티브 코드로 작성된 기존 라이브러리를 사용한다. (레거시 데이터를 사용하는 레거시 라이브러리)
    • 성능 개선 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성한다.
  • 성능을 개선할 목적으로 네이티브 메소드를 사용하는 것은 거의 권장하지 않다. (java 3 이전 제외)

  • 저수준의 자원이나 네이티브 라이브러리를 사용해야만 하는 경우는 어쩔수 없더라도 네이티브 코드는 최소한만 사용하고 철저하게 테스트하자.

아이템 67. 최적화는 신중히 하라

  • 빠른 프로그램 보다는 좋은 프로그램을 작성하자.

  • 성능을 제한하는 설계를 피하자.

  • API를 설계할 때 성능에 주는 영향을 고려하자.

  • 성능을 위해 API를 왜곡하는 것은 매우 안좋다.

  • 어쩔수 없이 최적화는 하게 되는 경우는 각각의 최적화 시도 전후로 성능을 추천하자

아이템 68. 일반적으로 통용되는 명명 규칙을 따르자

  • 철자 규칙 : 패키지, 클래스, 인터페이스, 메소드, 필드, 타입변수의 이름을 다룬다.

    • 패키지 / 모듈명
      • 각 요소를 점(.)으로 이으며 계층적으로 짓는다
      • 모두 소문자 혹은 숫자로 짓는것이 좋다.
      • 도메인이 있다면 역순으로 사용하는 것이 좋다.
    • 클래스 / 인터페이스
      • 이름은 대문자로 시작해야 하며 줄여쓰지 않는것이 좋다.
      • 약자의 경우라도 첫글자만 대문자로 하는 것이 좋다.
    • 타입 매개변수명은 한 문자로 표현한다.
      • T: 임의의 타입, Type의 약자
      • E: 컬랙션의 원소 , Element의 약자
      • K,V: Map의 key, Value
      • X: 예외, Exception의 약자
      • R: 메소드의 반환 타입, Return의 약자
  • 문법규칙 : 논쟁의 소지가 있을 수 있으며, 유연하다.

    • 객체를 생성할 수 있는 클래스명은 보통 명사, 명사구를 사용한다. (ex. Thread)
    • 객체를 생성할 수 없는 클래스명은 보통 복수형 명사로 짓거나 형용사로 짓는다.
    • 메소드명은 동사, 동사구로 짓는다.
    • 해당 인스턴스의 속성을 반환하는 메소드는 명사 또는 get으로 시작하는 동사구로 짓는다. (boolean 제외)
    • 객체의 타입을 바꿔서 다른 타입의 또 다른 객체를 반환하는 메소드는 보통 to타입 형태로 짓는다. (toString, toArray, toPath 등)
    • 객체의 내용을 다른 뷰로 보여주는 메소드는 as타입 형태로 짓는다. (asList 등)
    • 객체의 값을 기본타입 값으로 반환하는 메소드는 타입 Value 형태로 짓는다. (intValue 등)

표준 명명 규칙을 체화 해서 자연스럽게 베어 나오도록 하는 것이 좋다.

profile
한참 열정이 가득한 백엔드 개발자입니다.

0개의 댓글