분류 전체보기
[이펙티브 자바] 클래스와 인터페이스를 유연하게 만드는 방법
클래스와 멤버의 접근 권한을 최소화하자 잘 설계된 컴포넌트는 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 숨겨, 구현과 API를 깔끔히 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통한다. [정보은닉, 캡슐화]라고 하는 이 개념은 소프트웨어 설계의 근간이 되는 원리다. 정보은닉 장점 시스템 개발 속도를 높인다. 여러 컴포넌트를 병렬로 개발할 수 있기 때문이다. 시스템 관리 비용을 나춘다. 컴포넌트가 모듈화되어 있어 더욱 쉽게 파악할 수 있고 교체하는 부담도 줄어든다. 소프트웨어 재사용성을 높인다. 큰 시스템을 제작하는 난이도를 낮춰준다. 성능 그 자체를 높여주지는 않지만, 성능 최적화에 도움 된다. → 컴포넌트들을 독립시켜 개발, 테스트, 최적화, 분석, 수정, 교체를 개별적으로 할..
[이펙티브 자바] Object 메소드 관련 규약 + Comparable
equals 재정의 equals를 재정의할 때는 논리적 동치성을 비교할 때이며 Object 명세에 적힌 규약을 따라줘야한다. 반사성 null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 true다. 객체는 자기 자신과 같아야한다. 대칭성 null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)가 true면 y.equals(x)도 true이다. 두 객체는 서로에 대한 동치 여부에 똑같이 답해야 한다. 추이성 null이 아닌 모든 참조 값 x,y,z에 대해, x.equals(y)가 true이고 y.equals(z)도 true면 x.equals(z)도 true다. 삼단논법을 생각하면 이해하기 쉽다. 일관성 null이 아닌 모든 참조 값 x,y에 대해, x.equals(y)를 반복해서 호출..
[이펙티브 자바] try-finally 보다 try-with-resources 사용하자
꼭 회수해야 하는 자원은 try-with-resources를 사용하자 try-finally의 단점 우리는 자원의 닫힘을 보장하는 수단으로 try-finally를 써왔다. static void copy(String src, String dst) throws IOException{ InputStream in = new FileInputStream(src); try { OutputStream out = new FileOutputStream(dst); try { byte[] buf = new byte[BUFFER_SIZE]; int n; while ((n = in.read(buf)) >= 0) out.write(buf, 0, n); } finally { out.close(); } }finally { in.clo..
[이펙티브 자바] 불필요한 객체 생성을 피하고, 다 쓴 객체 참조를 해제하자
객체는 재사용할 수 있으면 재사용하자! 예를 들어 문자열이 로마 숫자 인지 확인하는(유효한 패턴을 갖고 있는지 확인하는) 메소드이다. 아래와 같은 코드로 작성하게 되면 문자열을 확인할 때마다 Pattern을 생성해주어야 한다. 정규표현식을 표현하는 Pattern은 입력받은 정규표현식에 해당하는 유한 상태 머신을 만들기 때문에 인스턴스 생성 비용이 높다. static boolean isRomanNumeralSlow(String s) { return s.matches("^(?=.)M*(C[MD]|D?C{0,3})" + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$"); } 아래와 같이 정규표현식을 표현하는 불변인 Pattern 인스턴스를 클래스 (정적) 초기화 과정에서 직접 생성하여 캐싱해두..
[이펙티브 자바] 자원 직접 명시보다는 의존 객체 주입을 사용하기
클래스들은 하나 이상의 자원에 의존하는 경우가 많다. 정적 유틸리티를 사용한 예시) public class SpellChecker{ private static final Lexicon dictionary = ...; private SpellChecker(){} } 싱글턴을 사용한 예시) public class SpellChecker{ private final Lexicon dictionary = ...; private SpellChecker(...){} public static SpellChecker INSTANCE = new SPellChecker(...); } 자원을(dictionary) 다른 구현 클래스로 교체해야 한다면 번거로운 작업이 될 것이다. dictionary 필드에서 final 한정자를 ..
[이펙티브 자바] private 생성자나 열거 타입으로 싱글턴임을 보증하라
싱글턴(Singleton) 싱글턴: 인스턴스를 오직 하나만 생성할 수 있는 클래스 무상태(stateless) 객체 설계상 유일해야 하는 시스템 컴포넌트 클래스를 싱글턴으로 만들면 테스트하기가 어려워질 수 있다. 타입을 인터페이스로 정의하여 구현체를 만든 싱글턴이 아니라면, 인스턴스를 가짜(mock) 구현으로 대체할 수 없기 때문 싱글턴 만드는 방식 1) public static 멤버가 final 필드인 방식 public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { } public void leaveTheBuilding() {...} } Elvis 클래스가 초기화될 때 만들어진 인스턴스가 전체 시스템에서 ..
[이펙티브 자바] 생성자에 매개변수가 많다면 빌더를 고려하라
생성자나 정적 팩터리에 선택적 매개변수가 많을 때 대응하기가 어렵다. 매개변수가 많은 경우 어떤 식으로 개발자들은 처리했는지 다음을 봐보자. 1. 점층적 생성자 패턴 프로그래머들은 선택적 매개변수에 대응하는 방법으로 점층적 생성자 패턴을 이용하였다. 필수 매개변수만 받는 생성자 필수 매개변수 + 선택 매개변수 1개를 받는 생성자 필수 매개변수 + 선택 매개변수 2개를 받는 생성자 ... 형태로 선택 매개변수를 전부 다 받는 생성자까지 늘려 만드는 방식이다. 보통 이런 점층적 생성자 패턴 방법을 사용하면 사용자가 설정하길 원치 않는 매개변수까지 포함할 수 있는데, 어쩔 수 없이 그런 매개변수에도 값을 지정해줘야 한다. 때문에 매개변수 개수가 많아지면 클라이언트 코드의 가독성 및 작성이 어려워진다. 2. 자..
[이펙티브 자바] 생성자 대신 정적 팩터리 메소드를 고려하라
정적 팩터리 메소드가 생성자보다 좋은 장점 1. 이름을 가질 수 있다. 한 클래스에 시그니처가 같은 생성자가 여러 개가 되면 생성자만으로는 각각의 차이를 들어내기가 쉽지 않다. 정적 팩터리 메소드를 사용하면 각각의 차이가 잘 드러나게 할 수 있다. 2. 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다. 불변 클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 식으로 불필요한 객체 생성을 피할 수 있다. 생성 비용이 큰 객체가 자주 요청되는 상황이라면 이와 같은 방식이 성능을 올려준다. public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } //객체를 생성하지 않는 예 Boo..