본문 바로가기
Web

[Spring] Factory-Method Pattern

by DuncanKim 2022. 7. 23.
728x90

[Spring] Factory-Method Pattern

 

팩토리는 공장을 의미한다. 공장은 물건을 생산하는데 객체 지향에서 팩토리는 '객체'를 생성한다. 팩터리 메서드는 결국 객체를 생성하고 반환하는 메서드를 말한다. 여기에 패턴이 붙으면 하위 클래스에서 팩토리 메서드를 오버라이딩해서 객체를 반환하게 하는 것을 의미한다.

 

팩토리 메서드 패턴은 생성할 객체 타입을 예측할 수 없을 때 활용한다. 객체 생성의 책임을 하위 클래스에게 위임시키고, 어느 하위 클래스에게 위임했는 지에 대한 정보를 은닉할 때 활용한다.

 

정리하면 다음과 같다.

 

- 팩토리 메서드 패턴은 어떤 클래스가 자신이 생성해야 하는 객체의 클래스를 예측할 수 없을 때 사용한다.
- 팩토리 메서드 패턴은 생성할 객체를 기술하는 책임을 자신의 서브클래스가 지정했으면 할 때 사용한다.

'객체 생성'을 하는 코드를 분리하여 클라이언트 코드와 결합도를 낮추는 것이다. 코드를 건드리는 횟수가 최소화된다.

 

 

1) 팩토리-메서드 패턴의 예시

 

아래의 코드에서는 '오리공장'이라는 서브 클래스가 객체를 생성하고 있다. 이렇게 되면, 인스턴스를 필요로 하는 main에서 '오리' 클래스의 서브 클래스에 대한 정보를 모른 채로 인스턴스를 생성할 수 있는 것이다. 

public class Main {
    public static void main(String[] args) {
        오리 a청둥오리 = 오리공장.get("청둥");
        오리 a흰오리 = 오리공장.get("흰");
        오리 a고무오리 = 오리공장.get("고무");
        오리 a고무2오리 = 오리공장.get("고무2");
        오리 a로봇오리 = 오리공장.get("로봇");

        a청둥오리.날다();
        // 출력 : 청둥오리 : 날개로 날아갑니다.
        a청둥오리.울다();
        // 출력 : 청둥오리 : 꽥꽥!!

        a흰오리.날다();
        // 출력 : 흰오리 : 날개로 날아갑니다.
        a흰오리.울다();
        // 출력 : 흰오리 : 꽥꽥!!

        a고무오리.날다();
        // 출력 : 고무오리 : 저는 날 수 없어요. ㅠㅠ
        a고무오리.울다();
        // 출력 : 고무오리 : 삑!삑!

        a고무2오리.날다();
        // 출력 : 고무오리 : 저는 날 수 없어요. ㅠㅠ
        a고무2오리.울다();
        // 출력 : 고무오리 : Peek!Peek!

        a로봇오리.날다();
        // 출력 : 로봇오리 : 로켓파워로 날아갑니다!!
        a로봇오리.울다();
        // 출력 : 로봇오리 : 기계는 울 수 없습니다.

        a고무2오리.set비행아이템(new 로켓파워비행아이템());
        a고무2오리.날다();
        // 출력 : 고무오리 : 로켓파워로 날아갑니다!!
    }
}

class 오리 {
    private String 종류;
    private 울음아이템 a울음아이템;
    private 비행아이템 a비행아이템;

    public 오리(String 종류) {
        this.종류 = 종류;
    }

    public void 날다() {
        System.out.printf("%s : ", 종류);
        a비행아이템.작동();
    }

    public void 울다() {
        System.out.printf("%s : ", 종류);
        a울음아이템.작동();
    }

    public void set울음아이템(울음아이템 a울음아이템) {
        this.a울음아이템 = a울음아이템;
    }

    public void set비행아이템(비행아이템 a비행아이템) {
        this.a비행아이템 = a비행아이템;
    }
}

class 오리공장 {
    public static 오리 get(String 종류) {
        오리 a오리 = new 오리(종류);

        switch (종류) {
            case "흰":
            case "청둥":
                a오리.set비행아이템(new 날개비행아이템());
                a오리.set울음아이템(new 꽥울음아이템());
                break;
            case "고무":
                a오리.set비행아이템(new 못나는비행아이템());
                a오리.set울음아이템(new 삑울음아이템());
                break;
            case "고무2":
                a오리.set비행아이템(new 못나는비행아이템());
                a오리.set울음아이템(new Peek울음아이템());
                break;
            case "로봇":
                a오리.set비행아이템(new 로켓파워비행아이템());
                a오리.set울음아이템(new 못우는울음아이템());
                break;
        }

        return a오리;
    }
}

interface 아이템 {
    void 작동();
}

interface 비행아이템 extends 아이템 {
}

interface 울음아이템 extends 아이템 {
}

class 날개비행아이템 implements 비행아이템 {
    @Override
    public void 작동() {
        System.out.println("날개로 날아갑니다.");
    }
}

class 못나는비행아이템 implements 비행아이템 {
    @Override
    public void 작동() {
        System.out.println("저는 날 수 없어요. ㅠㅠ");
    }
}

class 로켓파워비행아이템 implements 비행아이템 {
    @Override
    public void 작동() {
        System.out.println("로켓파워로 날아갑니다!!");
    }
}

class 꽥울음아이템 implements 울음아이템 {

    @Override
    public void 작동() {
        System.out.println("꽥꽥!");
    }
}

class 삑울음아이템 implements 울음아이템 {
    public void 작동() {
        System.out.println("삑삑!");
    }
}

class Peek울음아이템 implements 울음아이템 {
    public void 작동() {
        System.out.println("PeekPeek!");
    }
}

class 못우는울음아이템 implements 울음아이템 {
    public void 작동() {
        System.out.println("저는 울 수 없습니다.");
    }
}

 

 

2) 팩토리-메서드 패턴의 장, 단점

 

(1) 장점

: 클라이언트 코드로부터 서브 클래스의 인스턴스화를 제거하여 서로 간의 종속성을 낮추고, 결합도를 느슨하게 하며, 확장을 쉽게한다.

: 클라이언트와 구현 객체들 사이에 추상화를 제공한다.

 

 

(2) 단점

: 클래스가 많아진다. 제품 클래스가 바뀔 때마다 새로운 서브클래스를 생성해야 한다.

: 클라이언트가 creator 클래스를 반드시 상속해서 product를 생성해야 한다.

728x90

'Web' 카테고리의 다른 글

[Web] Web Request, Response(웹의 요청과 응답)  (0) 2022.07.25
[Spring] Observer Pattern  (0) 2022.07.24
[Spring] Singleton Pattern  (0) 2022.07.22
[Java] equals()와 ==의 차이점  (0) 2022.07.19
[Java] Wrapper 클래스  (0) 2022.07.18

댓글