객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패 턴이자 상속 관계에 있는 두 클래스에서 상위 클래스가 중요한 뼈대를 결 정하고, 하위 클래스에서 객체 생성에 관한 구체적인 내용을 결정하는 패턴.
예를 들어 어떤 클래스에서 다른 클래스의 객체를 생성해서 사용 하는 경우가 있음.
Americano americano = new Americano();
이 코드가 카페 클래스에 있다면 나중에 Americano() 클래스를 수정할 경우 카페 클래스도 수정 될 가능성이 높아져서 코드의 유연성이 떨어짐.
이 경우 인터페이스나 추상클래스에 맞춰서 코딩을 하면 시스템에서 일어나는 여러 변화에 대응할 수 있음.
슈퍼 클래스에 중요 기능을 추상 메서드 등을 사용해 중요한 뼈대 를 만들고, 카페 클래스에는 다형성을 이용해서 인스턴스를 주입받아서 사용을 함.
객체를 생성해서 주입하는 클래스( CoffeeFactory)를 만듬.
Coffee coffee = CoffeeFactory.getCoffee("Americano");
package chapter20230829.FactoryPattern;
abstract class Coffee { // 수퍼 클래스. 중요한 뼈대를 결정
public abstract int getPrice(); // 추상메서드
@Override
public String toString() {
return "Hi this coffee is " + this.getPrice();
}
}
class DefaultCoffee extends Coffee {
private int price;
public DefaultCoffee() {
this.price = -1;
}
@Override
public int getPrice() {
return this.price;
}
}
class Latte extends Coffee {
private int price;
public Latte(int price) {
this.price = price;
}
@Override
public int getPrice() {
return this.price;
}
}
class Americano extends Coffee {
private int price;
public Americano(int price) {
this.price = price;
}
@Override
public int getPrice() {
return this.price;
}
}
class CoffeeFactory { // 객체를 생성하는 클래스
public static Coffee getCoffee(String type, int price) {
/*
객체를 생성해서 반환, 정적메서드 사용으로 객체 생성없이 사용 가능
매개 변수에 따라서 다른 객체를 생성
*/
if (type.equalsIgnoreCase("Latte")) { // String.equalsIgnoreCase() : 대소문자 구별없이 비교
return new Latte(price);
}
else if (type.equalsIgnoreCase("Americano")) {
return new Americano(price);
}
else {
return new DefaultCoffee();
}
}
}
public class test01 {
public static void main(String[] args) {
// Latte 클래스가 변경이 되더라도 test01 클래스는 수정을 최소화
Coffee latte = CoffeeFactory.getCoffee("Latte", 4000);
Coffee americano = CoffeeFactory.getCoffee(("Americano"), 3000);
System.out.println("Factory latte : " + latte);
System.out.println("Factory americano : " + americano);
}
}