인터페이스가 추상 클래스보다 우선인 이유

    자바가 제공하는 다중 구현 메커니즘 - Interface (자바 8부터 default 메서드 제공) - Abstract Class 인터페이스와 추상 클래스 공통점 선언 내용은 존재, 하지만 구현 내용은 없음(추상 메서드를 가진다) 인스턴스 생성이 불가하다. 각각의 목적 인터페이스 Has - A 관계 : 함수의 껍데기만 존재하여 구현을 강제화 함 이를 통해 구현 객체가 같은 동작을 하도록 보장 다중 상속 - 여러개의 인터페이스를 구현이 가능하다. 인스턴스 필드를 가질 수 없고, public이 아닌 정적 멤버도 가질 수 없다(자바 9 부터 private static 메서드 구현 가능) 추상 클래스 IS - A 관계 : 추상 클래스를 상속하여 해당 클래스의 기능을 이용하고 또는 기능을 추가한다. 다중 상속 -..

    Clean Code - #6 객체와 자료 구조

    우리는 남들이 변수에 의존하지 않기 위해 변수를 비공개로 정의한다. (private) 그런데 왜 getter와 setter 를 당연히 public 으로 외부에 노출할까? 먼저 객체와 자료구조의 특징을 살펴보자 객체 동작을 공개하고 자료를 숨긴다. 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기 쉬운 반면, 기존 객체의 새 동작을 추가하기는 어렵다. 자료 구조 별다른 동작 없이 자료를 노출 기존 자료구조에 새 동작을 추가하기는 쉬우나, 기존 함수에 새로운 자료 구조를 추가하기는 어렵다. 우리는 사용자가 내부 구현 구조를 모른 채, 필요한 자료의 핵심만 조작할 수 있도록 클래스를 설계해야한다. 자료 추상화 객체의 변수 사이에 메서드를 넣는다고 구현을 외부로 숨길 수는 없다. 구현을 감추기 위해서는 추..

    equals 재정의

    일단, 결론부터 얘기하자면 Object Class를 믿고, equals 꼭 필요한 것이 아니면 재정의하지 말자 그래도 반드시 재정의를 해야할 때가 있을 수 있으니 고려하고 준수해야할 사항들을 살펴보도록 하자. # 재정의하지 않는 것이 좋은지 다시 확인 재정의하지 않는 것이 최선인 상황들이 존재한다. 각 인스턴스가 본질적으로 고유할 때 ex) 동작하는 개체를 표현하는 클래스 - Thread 인스턴스의 논리적 동치성(logical equality)을 검사할 일이 없을 때 상위 클래스에서 재정의한 equals가 하위클래스에서도 적절하게 동작할 때 Constructor Set / List / Map 은 모두 AbstractSet / AbstractList / AbstractMap 으로부터 상속받아서 그대로 사용..

    다 쓴 객체 참조 해제하기

    자바에서는 가비지 컬렉터(GC)가 사용하지 않는 객체들에 대해서 메모리를 알아서 관리해준다. 먼저 가비지 컬렉션에 대해 간단하게만 짚고 넘어가보자 # GC (Garbage Collection) 힙 영역 내의 참조되지 않는 객체가 아닌 Reachability 라는 개념을 통해 도달되지 않는 객체를 메모리에서 해제하여 메모리 관리를 해준다. 가비지 컬렉션의 동작 방식 Heap 에서의 Young 영역과 Old영역은 서로 다른 메모리 구조기 때문에, 세부적으로는 가비지 컬렉터가 다르게 동작하지만, 기본적으로 가비지 컬렉션은 2가지의 공통된 단계를 거친다. Stop The World 가비지 컬렉션을 실행하기 위해 JVM이 실행중인 GC를 진행하는 쓰레드를 제외한 모든 쓰레드의 작업을 중단하여 애플리케이션의 실행이..

    불필요한 객체 생성 피하는 방법

    static boolean isRomanNumeral(String s) { return s.matches(" ... "); } # 정적 팩토리 메서드 방법 똑같은 기능을 제공하는 객체를 반복적으로 생성하는 것보다 객체 하나를 재사용하는 것이 더 효율적 /* 실행될 때마다 new 를 통해 새로운 인스턴스 생성 - 쓸데없는 String 인스턴스가 계속해서 생성된다. */ String s = new String("Xonmin"); /* 하나의 String 인스턴스 생성 JVM 안에서 이와 똑같은 문자열 리터럴을 사용하는 모든 코드는 같은 객체를 재사용하게 된다. */ String s = "Xonmin"; 생성자 대신 정적 팩토리 메서드를 통해 불변 클래스에서 불필요한 객체 생성 회피 가변 객체라고 해도 사용 ..

    다중 instance 방지 & 의존성 주입[Dependency Injection]

    # 다중 인스턴스 방지 인스턴스화를 막기 위해서 private 생성자 사용하자 정적 메서드와 정적 필드만을 가진 클래스 기본 타입 , 배열 관련 메서드만 존재하는 클래스 ex) java.lang.Math , java.util.Arrays 특정 인터페이스를 구현하는 객체를 생성해주는 정적 메서드(팩토리)를 모아놓은 클래스 ex) java.util.Collections final 클래스와 관련한 메서드를 모아놓은 클래스 final 클래스를 상속해서 하위 클래스에 메서드를 넣는 것은 불가능 하기 때문 위와 같이, 정적 멤버만 담은 utility 클래스는 인스턴스로 만들려고 설계한 것이 아님 → 따라서 외부에서 해당 클래스의 생성자에 접근하지 못하게 해야함 하지만 생성자를 명시하지 않으면 자동으로 컴파일러는 d..

    Singleton 보장 방법

    private 생성자 / 열거 타입으로 Singleton을 보장하자 Singleton 인스턴스를 오직 하나만 생성할 수 있는 클래스 cf) instance =? 싱글턴이 필요한 상황 무상태 객체 - 함수 설계상 유일성이 보장되야 하는 시스템 컴포넌트 (ex - Spring 컨테이너가 각 클래스에 대해 딱 한개의 인스턴스만 생성) Thread-safe가 보장되어야 하는 상황 클래스를 싱글턴으로 만든다. → 해당 클래스를 사용하는 클라이언트를 테스트하기 어려워질 수 있다. 이유 : 하나의 자원을 공유하기 때문에 프로덕션 DB에 사용되는 싱글턴 클래스라면 인스턴스가 하나이다. 따라서 싱글턴 인스턴스를 가짜(mock) 구현으로 대체할 수 없기 때문이다. Singleton 을 만드는 방법 방법 #1 - publi..

    Builder 패턴

    정적 팩토리 메서드 , 생성자 - 매개변수가 많을 때, 선택적으로 고려해야한다면 불편함 존재 기존 해결 방법 : 점층적 생성자 패턴(Telescoping Constructor Pattern) 필수적인 파라미터들에 대한 생성자 설정 후, 선택적인 파라미터에 대해서는 해당 파라미터를 포함한 생성자를 연쇄적 호출 이를 통해 모든 파라미터들이 설정된 객체가 만들어진다. 장점 : 파라미터들이 유효한지를 생성자를 통해서 확인하면 일관성 유지 보장 문제점 : 클라이언트가 원하지 않는 파라미터까지 설정해야 한다. 개발자의 입장에서도 Class의 라인 수 증가, 호출 수 증가 - 클라이언트 코드를 작성하거나 읽기 어려운 문제 발생 자바빈즈 패턴(JavaBeans Pattern) 매개변수가 없는 생성자로 객체 생성 이후,..