Item 15 : 클래스와 멤버의 접근 권한을 최소화하라 잘 설계된 컴포넌트는 내부 구현을 완벽히 숨겨서, 구현과 API를 깔끔히 분리한다. 오직 API를 통해서만 다른 컴포넌트와 소통하며 서로의 내부 동작 방식에는 전혀 개의치 않는다. 여기서 말하는 것은 정보 은닉, 캡슐화이다. 정보 은닉의 장점은 컴포넌트들을 서로 독립시켜서 개발, 테스트, 최적화, 적용, 분석, 수정을 개별적으로 할 수 있게 해 준다. 정보 은닉, 캡슐화의 장점 개발 속도 향상 : 여러 컴포넌트를 병렬로 개발하는 것이 가능하다. 관리 비용 절감 : 각 컴포넌트를 더 빨리 파악할 수 있고, 다른 컴포넌트로 교체하는 부담도 적다. 성능 최적화에 기여 : 시스템 전체에서 최적화할 컴포넌트를 정해서, 특정 컴포넌트만 최적화할 수 있다. 재..
여러 문자열을 이어 붙일 때 보통 StringBuilder를 사용했었습니다. 그런데 특정 상황에서 더 유용한 클래스가 있어서 소개하려 합니다. StringBuilder를 썼을 때 아쉬운 점 아래와 같이 반복문으로 문자열을 이어 붙일 때 마지막에 구분자가 append 되는 것을 처리해야 하는 문제가 있다. String[] arr = {"one", "two", "three"}; StringBuilder sb = new StringBuilder(); for(int i = 0; i < arr.length; i++){ if(i == arr.length - 1){ sb.append(arr[i]); break; } sb.append(arr[i]).append(","); } System.out.println(sb); ..
깊은 복사 vs 얕은 복사 Java에서 객체를 복사할 때, 깊은 복사와 얕은 복사라는 개념이 있다. 간단하게 정리하자면 깊은 복사 : 실제 값을 새로운 메모리 공간에 복사하는 것이고, 얕은 복사 : 주소 값을 복사하는 것이다. 간단 예제 아래 예제를 통해 일단 간단히 알아보자. int[] original = new int[]{1,2,3}; int[] shallowCopy = original; //얕은 복사 int[] deepCopy = original.clone(); //깊은 복사 //주소 값 확인 System.out.println("주소-original = " + System.identityHashCode(original)); //주소-original = 191382150 System.out.print..
Java의 모든 객체는 Object 클래스를 상속받고 있다. Object 클래스는 객체의 동일성을 비교하기 위한 equals와 hashCode 메서드가 정의되어 있다. 따라서 Java의 모든 객체는 필요에 따라 equals와 hashCode를 재정의할 수 있다. equals() equals()는 두 객체의 값이 같은지 여부를 비교할 때 사용하는 메서드이다. 객체를 비교할 때 기본적으로 객체의 주소를 비교한다. public static void main(String[] args) { Car car1 = new Car(1111, "blue"); Car car2 = new Car(1111, "blue"); System.out.println(car1 == car2); //두 객체는 주소가 다르기 때문에 fals..
Item1 : 생성자 대신 정적 팩토리 메서드를 고려하라 클래스의 인스턴스를 얻는 가장 기본적이고 전통적인 방법은 public 생성자이다. new 키워드를 이용하여 인스턴스를 생성할 수 있다. Item item = new Item(); 이 방법과는 별도로 정적 팩토리 메서드(static factory method)를 제공하는 방법을 꼭 알아두면 좋다. 해당 클래스의 인스턴스를 반환하는 단순한 정적 메서드이다. 예를 들면 아래와 같이 primary type인 boolean의 boxing class Boolean에서 정적 팩토리 메서드를 이용해서 boolean을 Boolean으로 변환하는 메서드가 있다. public static Boolean valueOf(boolean b) { return (b ? TRU..
빈 스코프란? 스프링 빈은 기본적으로 싱글톤으로 관리된다. 그래서 스프링 컨테이너는 스프링 싱글톤 컨테이너라고 불리기도 한다. 그러나 이것은 스프링 빈이 기본적으로 싱글톤 스코프로 생성되기 때문이다. "스코프"는 빈이 존재할 수 있는 범위를 뜻한다. 한마디로 빈 스코프는 빈이 존재할 수 있는 범위 또는 빈의 라이프사이클의 범위라고 생각할 수 있을 것 같다. 스프링은 아래와 같이 다양한 빈 스코프를 지원한다. 싱글톤 : default, 스프링 컨테이너의 시작부터 종료까지 유지되는 가장 넓은 범위의 스코프 프로토타입 : 스프링 컨테이너는 빈의 생성과 의존성 주입까지만 관여하고, 더 이상 관리하지 않는 짧은 범위의 스코프 웹 관련 스코프 : request, session, application 등 여러 스코프..
Spring Bean LifeCycle Spring DI 컨테이너는 Bean으로 등록된 객체의 생명주기 관리를 위임받아서 관리하고, 객체가 필요한 곳에서 이 Bean을 의존성 주입받아서 사용할 수 있다. 스프링 컨테이너가 생성될 때 객체(Bean)를 생성하고 의존성을 주입하는데, 의존관계 주입 후 Bean을 초기화하고, 스프링 컨테이너를 종료하기 전에 객체를 소멸시켜야 한다. 객체의 생성과 초기화 분리 객체를 초기화 한다는 것은, 객체 생성 이외에 외부 커넥션을 연결하거나, 초기값을 등록하는 등의 여러 작업을 말한다. 이 과정을 생성자에서 진행해도 되지만, 객체 생성에 비해 초기화는 비교적 무거운 일을 수행하기 때문에 객체를 생성하는 부분과 초기화하는 부분을 명확하게 나누는 것이 좋다. 빈 생명주기 스프..
DI : Dependency Injection (의존성 주입) 의존성 주입은 객체 간의 의존성을 줄이고 유지보수성을 높이기 위해 사용된다. Spring 컨테이너에 여러 컴포넌트를 Bean으로 등록하여 생명주기 관리를 위임하고, 이 Bean으로 등록한 객체를 주입받아서 사용할 수 있다. DI 덕분에 개발자가 객체 생성에 대한 부분을 신경 쓰지 않고 비즈니스 로직에만 집중할 수 있게 된다. 의존성 주입 방법 의존성 주입 방법은 4가지가 있다. 생성자 주입 Setter 주입 Field 주입 일반 메서드 주입 이 중, 생성자 주입을 가장 많이 사용하고 Spring에서 권장하는 방법이다. 생성자 주입 생성자를 통해 의존성을 주입하는 방법이다. 생성자 호출 시점에 딱 한 번만 호출되는 것이 보장된다. 불변, 필수 ..