분류 전체보기
-
Finalizer와 Cleaner는 피하라JAVA/Effective java 2021. 1. 3. 23:16
Finalizer는 예측 불가능하고, 위험하며, 대부분 불필요하다. 그걸 쓰면 이상하게 동작하기도 하고, 성능도 안 좋아지고, 이식성에도 문제가 생길 수 있다. Finalizer를 유용하게 쓸 수 있는 경우는 극히 드물다. finalizer는 GC가 돌때 호출이 되는데 언제 호출되는지 예측할 수 없다. GC에 대상이 된다고 해서 바로 GC가 되는 것이 아니기 때문이다. 다음의 코드는 run() 실행 후 1초 있다가 종료되게 된다. run() 호출후의 finalizerExample의 레퍼런스는 유효하지 않게 되지만 실행해보면 Clean Up을 실행하지는 않는다. GC에 대상은 되지만 바로 되지는 않는다. 그럼 언제 써야 될까? 딱 두가지 경우 안전망 역할로 자원을 반납하고자 하는 경우. 네이티브 리소스를 ..
-
더이상 쓰지 않는 객체 레퍼런스는 없애자 + Weak ReferenceJAVA/Effective java 2021. 1. 2. 20:41
메모리 직접 관리 자바에 GC (가비지 콜렉터)가 있기 때문에 메모리 관리에 대해 신경 쓰지 않아도 될 거라고 생각하기 쉽지만 그렇지 않다. 다음 코드를 살펴보자. 여기서의 size는 index에 역할을 하고 있다. pop()을 보면 내가 넣을 장소가 아닌 뺄 장소로 이동해야 하기 때문에 먼저 --size를 하고 반환한다. 배열은 계속해서 값을 넣기만 하고 없어지지는 않는다. 스택에 계속 쌓다가 많이 빼냈다고 치자, 그래도 스택이 차지하고 있는 메모리는 줄어들지 않는다. 왜냐면 저 스택의 구현체는 필요없는 객체에 대한 레퍼런스를 그대로 가지고 있기 때문이다. 가용한 범위라는 것은 실제 유의미한 element를 가지고 있는 범위이고 이는 size 보다 작은 부분들이다. 그 값 보다 큰 부분에 있는 값들은 ..
-
불필요한 객체를 만들지 말자JAVA/Effective java 2021. 1. 1. 22:37
기능적으로 동일한 객체를 새로 만드는 대신 객체 하나를 재사용하는 것이 대부분 적절하다. 재사용하면 새로운 객체를 만들지 않기 때문에 성능적으로 더 빠르다. 그리고 불변 객체들은 항상 재사용할 수 있다. 문자열 객체 생성 자바의 문자열, String을 new로 생성하면 항상 새로운 객체를 만들게 된다. == 로 주소값을 비교한 name과 name2의 값은 false가 나온다. name에서 힙에 메모리가 할당되고 new로 또 다시 생성했기 때문에 name2에서 새로운 메모리가 할당되어 힙에 생성된다. 따라서 다음과 같이 String 객체를 생성하는 것이 올바르다. String s = "bikini"; 문자열 리터럴을 재사용하기 때문에 해당 자바 가상 머신에 동일한 문자열 리터럴이 존재한다면 그 리터럴을 재..
-
리소스를 엮을 때는 의존성 주입을 선호하라JAVA/Effective java 2020. 12. 31. 18:28
대부분의 클래스는 여러 리소스에 의존한다. 여기서 말하는 리소스는 의존성이다. 이 책에서는 SpellChecker와 Dictionary를 예로 들고 있다. SpellChecker 클래스는 스펠링이 맞는지 확인하는 클래스이고 Dictionary는 사전 클래스이다. 이때 SpellCheck가 Ditionary를 사용하고, 이를 의존하는 리소스 또는 의존성이라고 부른다. 이때 SpellChecker를 다음과 같이 구현하는 경우가 있다. 부적절한 구현 static 유틸 클래스 static 유틸리티 클래스이고 인스턴스로 만들 이유가 없기에 private 한 생성자를 만들었다. public static 한 메서드를 사용해서 클라이언트들이 SpellChecker.isValid 식으로 유틸 클래스를 사용하도록 한다. ..
-
private 생성자로 noninstantiability를 강제할 것JAVA/Effective java 2020. 12. 30. 15:08
단순히 static 메서드와 static 필드를 모아두는 유틸리티 클래스들을 만들고 싶을 때가 있다. OOP적 사고와는 다소 거리가 있지만 나름의 쓰임새는 있다. Arrays에 배열 관련 메서드, Collections에 정적 메서드 와 팩토리 등이 그 예이다. 또한 final 클래스와 관련된 메서드들을 모아놓을 때도 사용하게 된다. final 클래스를 상속해서 하위 클래스에 메서드를 넣는 것은 불가능하기 때문이다. 따라서 이같은 유틸리티 클래스는 인스턴스를 만들어 쓰려고 설계한 게 아니다. 하지만 생성자를 명시하지 않으면 생성되는 기본 생성자는 public한 생성자이다. 클라이언트는 이 생성자가 자동 생성된 것인지 구분할 수 없다. 실제로 공개된 API들도 의도치 않게 인스턴스화할 수 있게 된 클래스가 ..
-
Aggregate와 Repository 3부JAVA/DDD 2020. 12. 30. 14:18
유창하게(Fluently) 구현하기 AGGREGATE와 ENTRY POINT, REPOSITORY를 사용하여 대략적인 도메인 모델을 만들었다. 이제 테스트 주도 방식을 적용하여 도메인 로직을 개발해보자. 테스트 주도 개발 방식에서는 애플리케이션 코드를 작성하기 전에 실패하는 테스트부터 작성한다. 테스트를 작성할 때는 테스트 대상 객체의 인터페이스가 어떻게 사용될 지를 상상해 보는 것이 중요하다. 테스트 중인 시나리오를 실행하기 위해 객체의 어떤 오퍼레이션을 어떤 순서로 호출하는 것이 효율적인지를 결정한다. 따라서 테스트를 작성함과 동시에 자연스럽게 사용하기 편리한 인터페이스를 설계하게 되는 부수적인 효과도 얻을 수 있다. 객체의 인터페이스 설계와 관련해서 FLUENT INTERFACE라는 방식이 있다. ..
-
private 생성자 또는 enum 타입을 사용해서 싱글톤으로 만들 것JAVA/Effective java 2020. 12. 29. 19:35
싱글톤은 흔히 쓰는 용어이다. 하나의 패턴의 이름이고 App을 통틀어서 해당 클래스의 인스턴스가 하나만 사용하는 패턴을싱글톤이라고 한다. 간단하게 싱글톤 패턴을 요약해보면 자기 타입에 대한 인스턴스를 private static으로 만들어 놓는다. private 한 생성자를 만든다. 이제 이 타입의 인스턴스는 new를 통해 만들 수 없다. static 한 get메서드를 통해서 이 하나의 인스턴스를 가져다가 쓸 수 있다. ( multi-thread 등의 환경을 고려한다면 좀 더 복잡한 형태가 될 것 ) 이처럼 오직 한 인스턴스만 만드는 클래스를 싱글톤이라 부른다. 보통 함수 같은 Stateless 객체 또는 본질적으로 유일한 시스템 컴포넌트를 그렇게 만든다. 싱글톤의 단점으로는 사용하는 클라이언트 코드를 테..
-
AGGREGATE와 REPOSITORY 2부JAVA/DDD 2020. 12. 29. 18:21
AGGREGATE AGGREGATE는 데이터 변경 시 하나의 단위로 취급할 수 있는 연관된 객체들의 클러스터이다. 각 AGGREATE는 루트(root)와 경계(boundary)를 가진다. 경계는 AGRREGATE 내부에 무엇이 포함되어야 하는지를 정의한다. 루트는 AGGREGATE 내에 포함된 하나의 REFERENCE OBJECT이다. 루트는 외부에서 참조 가능한 유일한 AGGREGATE의 내부 객체이다. 외부에서는 루트 객체만이 참조 가능하지만 AGGREGATE 내부의 객체는 외부 객체를 자유롭게 참조할 수 있다. 루트를 제외한 나머지 REFERENCE OBJECT들은 외부로부터 접근이 불가능하기 때문에 지역 식별자(local identity)를 가진다. 지역 식별자는 AGGREGATE 내부에서 REF..