전체 글
마커 인터페이스(Marker Interface)
마커 인터페이스 : 아무 메서드도 선언되어있지 않고, 단지 자신을 구현하는 클래스가 특정 속성을 가짐을 표시하는 인터페이스 ex) Serializable : 자신을 구현한 클래스의 인스턴스는 ObjectOutputStream을 통해 Write(Serialization)이 가능하다는 것을 알려줌 마커 어노테이션이 등장하면서 마커 인터페이스는 구식이 되었다고들 얘기하지만, 사실은 그렇지 않다. # 마커 인터페이스의 장점 마커 인터페이스는 이를 구현한 클래스의 인스턴스들을 구분하는 타입으로 쓸 수 있으나, 마커 어노테이션은 그렇지 않다. 마커 인터페이스는 어엿한 타입이므로, 마커 어노테이션을 사용했다면 런타임 때 발견될 오류를 컴파일 타임에 잡을 수 있다. ObjectOutputStream.writeObjec..
@Override 어노테이션 사용법
@Override - 메서드 선언에만 달 수 있으며, 이 어노테이션의 의미는 상위 타입(부모 타입)의 메서드를 재정의했음을 의미한다. @Override 어노테이션을 일관되게 사용한다면 여러 악명 높은 버그들을 예방할 수 있는 아주 좋은 습관이라고 말할 수 있다. Ex) 영어 알파벳 2개로 구성된 문자열을 표현하는 클래스 //버그를 찾아보자 public class Bigram { private final char first; private final char second; public Bigram(char first, char second) { this.first = first; this.second = second; } public boolean equals(Bigram bigram) { return b..
CleanCode - Chapter 11. System
서론 : 도시 만들기 거대한 도시가 돌아가는 이유 : 각각의 전원, 교통 등이 모듈로 모듈화되어 관리 / 일정 수준의 추상화를 통해 큰 도시 전체에 대한 이해 없이 개인과 개인이 관리하는 구성요소를 통해 효율적으로 동작 SW = 하나의 도시 - 하나의 도시의 모듈화만큼의 추상화를 이루지 못하는 것이 클린코드답지 못한 문제 낮은 단계의 추상화를 통해 관심사(Concern)을 분리하고 높은 추상화 수준(시스템 수준)에서도 클린 코드를 유지해보자 # 시스템의 생성(제작)과 사용을 분리 public Service getService() { if (service == null) service = new MyServiceImpl(...); // Good enough default for most cases? ret..
클래스 계층 구조를 활용하기
# 태그 달린 클래스 두 가지 이상의 의미를 표현할 수 있고, 그 중 현재 표현하는 의미를 태그 값으로 알려주는 클래스 class Figure { enum Shape { RECTANGLE, CIRCLE }; // 태그 필드 - 현재 모양을 나타낸다. final Shape shape; // 다음 필드들은 모양이 사각형(RECTANGLE)일 때만 쓰인다. double length; double width; // 다음 필드는 모양이 원(CIRCLE)일 때만 쓰인다. double radius; // 원용 생성자 Figure(double radius) { shape = Shape.CIRCLE; this.radius = radius; } // 사각형용 생성자 Figure(double length, double wi..
인터페이스 - 타입을 정의하는 용도로만 사용하기
인터페이스의 역할 인터페이스는 자신을 구현한 클래스의 인스턴스를 참조할 수 있는 타입 역할을 한다. → 클래스가 인터페이스를 구현한다는 것 : 자신의 인스턴스로 무엇을 할 수 있는 지 의미를 전달 인터페이스는 위에서 언급한 용도로만 사용되어야 한다. 잘못된 인터페이스의 용도 상수 인터페이스 상수 인터페이스 : 메서드 없이, 상수를 뜻하는 static final 필드로 구성된 인터페이스 public interface PhysicalConstants { // 아보가드로 수 (1/몰) static final double AVOGADROS_NUMBER = 6.022_140_857e23; // 볼츠만 상수 (J/K) static final double BOLTZMANN_CONSTANT = 1.380_648_52e..
인터페이스 설계 - 구현하는 개발자를 생각하자
# default Method 자바 8 이전 기존 구현체를 깨뜨리지 않고, 인터페이스에 메서드 추가 방법 전무후무 - 인터페이스에 메서드 추가하면 대부분 컴파일 오류 발생 - 추가된 메서드가 기존 구현체에 존재할 가능성 희박 자바 8 이후 기존 인터페이스에 메서드를 추가할 수 있도록 디폴트 메서드 추가 핵심 컬렉션 인터페이스들에 많은 디폴트 메서드 추가 for lambda 활용 디폴트 메서드 선언시, 그 인터페이스를 구현한 후에 디폴트 메서드를 재정의하지 않은 모든 클래스에서는 디폴트 구현이 사용 단, 디폴트 메서드는 구현 클래스에 대한 정보 없이 무작정 삽입(추가) 된 것이므로 주의해야 한다. 자바 라이브러리의 디폴트 매서드는 코드 품질이 높고 범용적이므로 대부분의 상황에서 잘 작동 하지만, 생각할 수..
인터페이스가 추상 클래스보다 우선인 이유
자바가 제공하는 다중 구현 메커니즘 - Interface (자바 8부터 default 메서드 제공) - Abstract Class 인터페이스와 추상 클래스 공통점 선언 내용은 존재, 하지만 구현 내용은 없음(추상 메서드를 가진다) 인스턴스 생성이 불가하다. 각각의 목적 인터페이스 Has - A 관계 : 함수의 껍데기만 존재하여 구현을 강제화 함 이를 통해 구현 객체가 같은 동작을 하도록 보장 다중 상속 - 여러개의 인터페이스를 구현이 가능하다. 인스턴스 필드를 가질 수 없고, public이 아닌 정적 멤버도 가질 수 없다(자바 9 부터 private static 메서드 구현 가능) 추상 클래스 IS - A 관계 : 추상 클래스를 상속하여 해당 클래스의 기능을 이용하고 또는 기능을 추가한다. 다중 상속 -..
Clean Code - #6 객체와 자료 구조
우리는 남들이 변수에 의존하지 않기 위해 변수를 비공개로 정의한다. (private) 그런데 왜 getter와 setter 를 당연히 public 으로 외부에 노출할까? 먼저 객체와 자료구조의 특징을 살펴보자 객체 동작을 공개하고 자료를 숨긴다. 기존 동작을 변경하지 않으면서 새 객체 타입을 추가하기 쉬운 반면, 기존 객체의 새 동작을 추가하기는 어렵다. 자료 구조 별다른 동작 없이 자료를 노출 기존 자료구조에 새 동작을 추가하기는 쉬우나, 기존 함수에 새로운 자료 구조를 추가하기는 어렵다. 우리는 사용자가 내부 구현 구조를 모른 채, 필요한 자료의 핵심만 조작할 수 있도록 클래스를 설계해야한다. 자료 추상화 객체의 변수 사이에 메서드를 넣는다고 구현을 외부로 숨길 수는 없다. 구현을 감추기 위해서는 추..