DevBoi

[Effective Java] Rules 본문

Language/[Java]

[Effective Java] Rules

HiSmith 2022. 4. 21. 17:35
반응형

[53. Null 대신 빈 배열이나 컬렉션 사용]

Null처리를 해줘야 하는데, 이를 잊은 경우 클라이언트 측에서 오류 발생가능

 

[3. private 생성자나 열거 타입으로 싱글턴임을 보증하라]

 

  <싱글 턴 구현 방법>

   1. public final 을 이용하는 방법

private 생성자는 public static final 필드인 Instance를 초기화 할때 한번만 호출된다.

리플렉션기능을 통해 private 생성자를 호출할수 있다 -> 두번째 객체 생성 부터는 예외 처리 필요

 

   2.정적 팩토리를 이용하는 방법

 

싱글턴에 대한 이해가 빠르다

API 를 변경하지 않고, 싱글턴 패턴을 포기할 수 있다.

(싱글턴에 대한 직렬화는, serializable impl 과 transient와 readResolve를 추가해야 가능하다, 아니면 역직렬화때 신규객체가 계속 생성된다) -> enum으로 해야 싱글턴을 안전하게 사용가능

 

[규칙4. 인스턴스화를 막으려거든 private 생성자를 사용하라]

 

만약 정적 클래스나, 정적 메소드 만을 모아 놓고 싶은 클래스가 있다면, 해당 클래스는 인스턴스화를 막아야한다.
abstract으로 생성하면, 하위클래스 만드는 순간 객체 생성이 가능하고, 생성자 생략하면, 컴파일러는 기본 생성자를 만든다.
-> private 생성자를 사용하여 외부에서 인스턴스를 생성 불가하게 만들어야 한다-> 하위클래스를 만들 수 없다.

 

 

[규칙 6. 불필요한 객체 생성을 피하라]

기능적으로 동일한 객체는 재사용 하는 편이 낫다.
극단적 Bad) String a = new String("this is sample")

 

isBabyBoomer메소드는 정적 변수들을 사용하여 처리한다.
즉 메소드 호출시, 불필요한 객체를 계속 재생성 하지 않아도 된다.

 

 

AutoBoxing을 지원하지만, 기본형 타입을 가능하다면, 하는게 좋다. (Long 은 long 보다 7배 느리다)

객체 생성 장점

- 생성자 안에서 하는일이 작고 명확하면, 객체 생성과 반환은 신속하게 이루어진다.

- 단순성을 높이고, 코드의 명확성을 높인다면 일반적으로 만드는 것이 좋다.

 

객체 생성 단점

생성 비용이 높은 객체들은 재사용하는 것이 맞다.

 

 

 

 

[규칙 1. 생성자 대신 정적 팩터리 메서드를 고려하라]

 

단순 생성자가 아닌, 정적 팩토리 메소드를 사용해서, 인스턴스를 제공할 수 있다.<장점>->생성자와 달리, 정적 팩터리 메소드에는 이름이 있다.->정적 팩터리 메서드는 이름을 잘 짓기만 한다면, 사용하기 쉽고 가동성도 높아진다.-> 생성자 보다 정적 팩토리 메서드는 용도를 파악하기 쉬워진다.-> 변경 불가능 클래스라면, 이미 만들어둔 객체를 활용 할 수 있다.(캐싱 후 재사용도 가능)-> 같은 객체를 반복 반환이 가능하여, 얼마나 존재할지를 정밀하게 제어할 수 있다.-> 반환되는 객체의 클래스를 훨씬 유연하게 결정할 수 있다.<단점>->public 이나 protected로 선언된 생성자가 없으므로 하위클래스를 만들 수 없다.-> 정적 팩터리 메서드가 , 다른 정적 메서드와 구분이 어렵다.(of,getInstance등 이름을 맞춘다)

 

 

[규칙18. 상속보다는 컴포지션을 사용하라]

계승의 문제, 하위클래스가 정상동작하기 위해서는, 상위클래스의 구현에 의존할 수 밖에 없다.상위 클래스가 수정되면, 하위 클래스는 망가진다.상위 클래스에서 하위클래스에서 참조가능한 변수로 리턴한다.

 

 

계승은 캡슐화 원칙을 침해하므로, 문제가 발생할 수 있다.

계승을 고려하지 않은 상위 클래스의 경우, 하위 클래스는 깨지기 쉽다.

 

 

[규칙20. 추상 클래스 보다는 인터페이스를 우선하라]

추상 클래스 -> 자료형을 사용하는데. 자바는 다중상속을 허용하지 않기 때문에 제약이 많아진다.인터페이스- 이미 있는 클래스를 새로운 인터페이스를 구현하도록 하는 것은 간단하다- 믹스인(선택적 선언을 하는 것) 인터페이스를 하기에 좋다.- 다중구현 가능, 여러개의 속성을 다중 구현이 가능하다

 

- 추상 골격 구현 클래스를 중요 인터페이스 마다 두면, 인터페이스의 장점과 추상 클래스의 장점을 결합할 수 있다.- 골격 구현 클래스가 있다면, 해당 클래스를 사용해 인터페이스를 구현하는 것이 가장 분명한 프로그래밍 방법,기존 클래스를 변경 할 수 없다면, 인터페이스를 직접 구현해도된다.

 

 

인터페이스는 다양한 구현이 가능한 자료형을 정의하는 일반적인 가장 좋은 방법이다(유연성)

유연 < 개선 인 경우, 추상클래스를 만들어야 하는데, 해당 단점을 잘 이해하고 있어야 한다.

중요한 인터페이스를 API에 포함하는 경우, 골격 구현 클래스를 함께 제공하면 어떨지 고려해야한다.

 

[규칙 12. toString을 항상 재정의 하라]

클래스의 toString 메서드는 일반적으로 사용자가 보려는 문자열이 아니다.

장점 : toString을 잘 구현한 클래스는, 디버깅하기 쉽다.

실전에서는 그 객체가 가진 주요정보 모두를 반환하는 것이 좋다.

(정적 유틸리티 클래스나, 열거타입은 이미 자바가 toString을 제공하니,따로 재정의 하지 않아도 된다.)

모든 구체 클래스에서 Object의 toString을 재정의하자

 

[규칙 16. public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하자]

 

public 클래스는 절대 가변 필드를 직접 노출하면, 안된다.

데이터 필드에 직접 접근할 수 있으니, 캡슐화의 이점을 제공하지 못한다.

API를 수정하지 않고, 내부 표현을 바꿀수 없고, 불변에 대한 보장을 할 수 없다.

외부에서 필드를 접근할 때 부수 작업을 수행할수도 없다.

 

[규칙 57. 지역변수의 범위를 최소화 하라]

지역변수의 유효범위를 최소로 줄이면, 코드 가독성과 유지보수성이 높아지고 오류 가능성이 낮아진다.

ex. while 보다, for를 쓰면, 반복문 지역변수에 대한 값이, for 괄호안으로 한정된다.

 

메서드를 작게 유지하고 한가지 기능에 집중하자.

- 한 메서드에서 여러가지 기능을 처리한다면, 그 중 한 기능만과 관련된 지역변수라도 다른 기능을 수행하는 코드에서

접근이 가능하다. -> 기능별로 쪼개는 것이 좋다.

-> 지역변수의 유효범위를 최소로 줄이면 코드 가독성과, 유지보수성이 높아지고, 오류 가능성이 낮아진다.

 

[규칙 58. 전통적인 for문 보다, for-each문을 사용]

 

for-each는  인덱스 변수를 사용하지 않아도 되어, 코드가 깔끔해지고, 오류날일도 없다.

1. 파괴적인 필터링 -> remove를 호출해야하기 때문에 for-each를 사용할수 없다.

2. 변형 -> 리스트나 배열을 순회 하면서, 그 원소의 값의 일부나 전체를 교체해야한다면 인덱스를 사용해야한다.

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

 

[규칙 15. 클래스와 멤버의 접근 권한을 최소화 하라]

잘 설계된 컴포넌트란, 모든 내부 구현을 완벽히 숨겨, 구현과 API를 깔끔하게 분리한다.

정보 은닉, 캡슐화를 하는 것은 소프트웨어 설계의 근간이 된다.

 

정보은닉의 장점 :
시스템을 구성하는 컴포넌트들을 서로 독립 시켜서 개발,테스트, 최적화,적용,분석,수정을 개별적으로 할수 있게 해준다.

1. 시스템 개발 속도를 높임 : 여러 컴포넌트를 병렬로 개발할 수 있기때문에 개발속도가 향상된다.

2. 시스템 관리 비용을 낮춤 : 각 컴포넌트를 더 빨리 파악하여 디버깅할 수있다. 다른컴포넌트로 교체하는 부담도 적다.

3. 성능 최적화에 도움을 준다 : 완성된 시스템을 프로파일링 하여 최적화할 컴포넌트를 정하고, 다른 컴포넌트에 영향을 주지 않고

해당 컴포넌트만 최적화 할수 있기 때문이다.

4. 소프트웨어 재 사용성을 높인다 : 외부에 의존 없이 동작할 수 있는 컴포넌트라면, 그와 함께 개발되지 않은 낯선 환경에서도 유용하게 쓰일 가능성이 크다.

5. 큰시스템을 제작하는 난이도를 낮춰준다.

시스템 전체가 완성되지 않은 상태에서도 개별 컴포넌트의 동작을 검증 할 수 있다.

 

프로그램 요소의 접근성은 , 가능한 최소한으로

- 꼭 필요한 것만 골라 최소한으로 public API를 설계하자

- public 클래스는 상수용 public static final 필드 외 어떠한 public 필드도 가지면 안된다.

-> public 클래스의 인스턴스 필드는 되도록 public 이 아니여야 한다. 만약 가변 필드를 자는 클래스는

쓰레드 세이프하지 않는다.

반응형

'Language > [Java]' 카테고리의 다른 글

[Java] Static이란?  (0) 2022.04.28
[Java] finalize 메서드 사용 및 메모리 점유  (0) 2022.04.28
[Java] 모니터  (0) 2022.04.08
[Java] 문맥 교환  (0) 2022.04.08
[Java] 멀티 쓰레드란  (0) 2022.04.08