면접을 위한 CS 지식공부 디자인패턴 - 팩토리 패턴

강성준·2024년 2월 20일

팩토리 패턴은
객체를 사용하는 코드에서 객체 생성 부분을 떼어내 추상화한 패턴이다.
쉽게 설명하자면 상위 클래스는 뼈대를 구성하고, 하위 클래스에서 객체 생성에 관한
구체적인 사항을 정의한다.

팩토리 패턴은 상속에 대한 이해가 있다면 쉽게 이해할 수 있다.
아래에서 자바 코드로 구현하면서 알아보자.


팩토리 패턴 구현

편의를 위해 추상 클래스 내에 inner class를 생성하여 코드를 작성하였다.
먼저 코드를 살펴보면 아래와 같이 구성되어있다.

  1. Coffee라는 추상클래스를 선언한다.
  2. CoffeeFactory라는 클래스를 선언한다. (타입에 따라 출력되는 문자열이 바뀐다.)
  3. DefaultCoffee, Latte, Americano 3개의 클래스를 선언한다. (모두 Coffee 추상클래스를 상속받는다.)
abstract class Coffee {
	public abstract int getPrice();
    
    @Override
    public String toString() {
		return "Hi this coffee is " + this.getPrice();
	}
    
    Class CoffeeFactory {		// 입력받은 타입에 따라 반환을 분기
    	public static Coffee getCoffee(String type, int price) {
        	if("Latte".equalsIgnoreCase(type)) {
            	return new Latte(price);
            } else if("Americano".equalsIgnoreCase(type)) {
            	return new Americano(price);
            } else {
            	return new DefaultCoffee;
            }
        }
    }
    
    // 기본 커피
    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;
        }
    }
}

이제 클래스를 하나하나 살펴보자

Coffee
멤버로 getPrice, ToString 메서드를 가지고 있다.
추상클래스이기 때문에 상속받는 하위 클래스(DefaultCoffee, Latte, Americano)는
상위 클래스의 추상메서드를 반드시 구현해야한다.

CoffeeFactory
말 그대로 Coffee를 찍어내는 공장의 역할을 하는 클래스이다.
getCoffee 메서드를 가지고 있고 매개변수로 커피 타입과 가격을 입력받는다.
입력받은 타입에 따라 분기하여 해당하는 타입의 클래스의 인스턴스를 생성해 반환한다.
Defaultcoffee, Latte, Americano 클래스 모두 Coffee를 상속받고 있어, Coffee 타입으로
모두 반환이 가능하다.

Defaltcoffee, Latte, Americano
Coffee 클래스를 상속받은 하위 클래스
생성자의 매개변수로 'price' 를 받아 자신의 필드 'price' 를 초기화한다.
Coffee 클래스의 메서드를 상속받아 getPrice 메서드를 구현한다.

이제 Main 메서드를 만들어 실행을 해보자.

public static void main(String[] args) {
	Coffee latte = CoffeeFactory.getCoffee("Latte", 4000);
    Coffee ame = CoffeeFactory.getCoffee("Americano", 3000);
    
    System.out.println("Factory latte :: " + latte);
    System.out.println("Factory ame :: " + ame);
}

결과
Factory latte :: Hi this coffee is 4000
Factory ame :: Hi this coffee is 3000


팩토리 패턴의 장점

위와 같이 팩토리 패턴을 이용하여 코드를 구현하면 무슨 장점이 있길래 이렇게 할까?
팩토리 패턴을 이용했을때 장점은 아래와 같다.

  1. 상위 클래스와 하위 클래스 분리로 인해 결합도가 낮아진다.
  2. 상위 클래스에선 인스턴스 생성 방식에 대해 알 필요가 없어 유연하다.
  3. 객체 생성로직이 분리되어 유지보수성이 증가한다.
  4. 팩토리 메서드가 분리되어 테스트에 용이하다.
  5. 확장성에 용이하다.(타입을 추가하기 쉽고 팩토리 메서드에 분기하나만 추가하면 된다.)

팩토리 패턴의 단점

이제 팩토리 패턴의 단점을 알아보자

  1. 코드의 양이 많아지고 추상화를 통하기 때문에 코드를 파악하기에 어려울 수 있음.
profile
Java, Spring Framework로 백엔드 개발을 하는 개발자입니다.

0개의 댓글