일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 스프링공부
- 프로그래머스
- JPA스터디
- JPA공부
- 알고리즘공부
- 기술공부
- 플러터 개발
- nestjs공부
- 카프카
- 스프링 공부
- JPA
- DDD
- K8S
- 기술면접공부
- 스프링부트
- 코테준비
- 스프링
- 스프링부트공부
- JPA예제
- nestjs스터디
- 플러터 공부
- 자료구조공부
- 자바공부
- Flutter
- Axon framework
- querydsl
- Kafka
- nestjs
- JPA 공부
- 코테공부
- Today
- Total
DevBoi
[Effective Java] Rules 본문
[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 |