이 그림을 보면서 이해해보자.
enum CoffeeType{
LATTE,
ESPRESSO
}
abstract class Coffee{ //커피 뼈대 (공통적 요소)
protected String name;
public String getName() {
return name;
}
}
class Latte extends Coffee{
public Latte() { //라떼를 만드는기술
name = "latte";
}
}
class Espresso extends Coffee{
public Espresso() { //에스프레소를 만드는 기술
name = "Espresso";
}
}
class CoffeeFactory {
public static Coffee createCoffee(CoffeeType type){ //enum으로 LATTE, ESSPRESSO를 고른다.
switch (type) { //요청에 맞게 해당 객체를 생성시켜준다.
case LATTE:
return new Latte();
case ESPRESSO:
return new Espresso();
default:
throw new IllegalArgumentException("invalid coffee type : " + type);
}
}
}
public class Main {
public static void main(String[] args) {
Coffee coffee = CoffeeFactory.createCoffee(CoffeeType.LATTE);
// 상위 클래스에 반환 받는다.
System.out.println(coffee.getName());
}
}
사용자 관점에서 해설
이런 느낌으로 생각하면서 코드를 오밀조밀 이해하면 된다.
그러나 우리는 개발자이다. 개발자로써의 관점에서 몇가지를 살펴 보겠다.
객체생성을 하지않고, 호출이 가능하기 때문에 해당 메서드에 대한 메모리 할당을 한 번만 할 수 있다.
정적메소드를 하지않았을 때 생기는 문제
이 것은 간단히 말하면 커피를 먹을 때마다 커피머신을 새로 만드는 행위랑 같다. 상식선에 이 것은 당연히 효율적이지 않다.
enum 클래스를 통해서 구분한다.
이는 단순히 가독성 및 enum 특성 상 구분에 용이하기 때문에 이를 활용하여 Factory 클래스 내부를 구성했다.
Enum 간단한 설명
Enum는 상수의 집합을 정의할 때 사용되는 타입이다.
예를 들어서 월, 일, 색상 등의 상수 값을 담는다. 자바에서는 enum는 다른 언어보다 더 활발히 사용되고, 상수가 아니라도 메소드 자체를 집어넣을 수 있다.
Enum을 기반으로 상수를 관리한다면, 로직 수정시 이 부분만 수정하면 된다는 장점이 있고, Enum 생성시 스레드세이프(Thread Safe)하기 때문에 싱글톤 패턴을 만들 때 도움이 된다. --> Enum 으로 싱글톤을 만들면 더 효율적일 수 있다는 말
스레드 안전(Thread-Satety)란 멀티 스레드 프로그래밍에서 일반적으로 어떤 함수나 변수, 혹은 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없는 것을 말한다.
Coffee는 Abstract 클래스이다.
공통된 특성(Common elements)에 대해서 집합요소로써 묶기 위해서 구성했고, 이를 상속 받아 고유의 특성을 추가 시켜 LATTE 그리고 ESSPRESSO 클래스를 구성할 수 있다.