본문 바로가기
java

Design Patterns - Factory Method

by 쭈꾸마뇽 2021. 11. 17.

구체적으로 어떤 인스턴스를 만들지는 서브 클래스가 정한다

다양한 구현체(Product)가 있고, 그중에서 특별한 구현체를 만들 수 있는 다양한 팩토리(Creator)를 제공할 수 있다.

 

확장에 열려있고 변경에 닫혀있는 구조로 만들어보자

public interface ShipFactory {

    default Ship orderShip(String name, String email) {
        validate(name, email);
        prepareFor(name);
        Ship ship = createShip();
        sendEmailTo(email, ship);
        return ship;
    }

    void sendEmailTo(String email, Ship ship);

    Ship createShip();

    private void validate(String name, String email) {
        if (name == null || name.isBlank()) {
            throw new IllegalArgumentException("배 이름을 지어주세요.");
        }
        if (email == null || email.isBlank()) {
            throw new IllegalArgumentException("연락처를 남겨주세요.");
        }
    }

    private void prepareFor(String name) {
        System.out.println(name + " 만들 준비 중");
    }

}

먼저 ShipFactory 인터페이스를 만든다.  ShipFactory는 Ship을 만드는 Creator역할을 하는 인터페이스이다.  기본적으로 Ship을 주문하고 만드는데 만드는 로직인 createShip 함수는 서브클래스에 구현을 하여 서브클래스가 결정하도록 한다.

public abstract class DefaultShipFactory implements ShipFactory {
    @Override
    public void sendEmailTo(String email, Ship ship) {
        System.out.println(ship.getName() + " 다 만들었습니다.");
    }
}

public class BlackShipFactory extends DefaultShipFactory {
    @Override
    public Ship createShip() {
        return new Blackship();
    }
}

public class WhiteShipFactory extends DefaultShipFactory {
    @Override
    public Ship createShip() {
        return new Whiteship();
    }
}

DefaultShipFactory는 ShipFactory를 상속받는 추상 클래스인데, 만약 자바 8 이상을 사용하고 있다면 인터페이스에 default 함수를 만들 수 있으므로 이 경우 생략이 가능하나 그 이하의 버전을 사용하고 있다면 default 함수는 중간에 추상클래스를 추가하여 작성해줘야 한다.

 

DefaultShipFactory를 상속하는 BlackShipFactory와 WhiteShipFactory는 구현클래스이다.  이 구현클래스가 직접 Ship을 만드는 로직을 구현하여 클라이언트에서는 원하는 Factory를 선택하여 원하는 객체를 만들 수 있다.

public class Client {

    public static void main(String[] args) {
        Client client = new Client();
        client.print(new WhiteShipFactory(), "whiteship", "keesun@mail.com");
        client.print(new BlackShipFactory(), "blackship", "keesun@mail.com");
    }

    private void print(ShipFactory shipFactory, String name, String email) {
        System.out.println(shipFactory.orderShip(name, email));
    }

}

클라이언트 코드를 보면 원하는 Factory를 선택하여 Ship을 만드는 것을 볼 수 있다.

 

질문

  1. 팩토리 메소드 패턴을 적용했을 때의 장점과 단점은? : 팩토리 메소드 패턴을 사용할 경우 기본의 if문이나 switch문으로 분기처리하여 로직을 작성했던 것을 클라이언트에서 원하는 방식을 선택하게 하여 분기처리 없이 로직을 추가할 수 있다.  단점은 새로운 로직이 추가될때마다 클래스를 추가해줘야 한다
  2. 확장에 열려있고 변경에 닫혀있는 객체 지향 원칙을 설명하세요 : 확장에 열려있고 변경에 닫혀있다는 것은 기존코드를 건드리지 않고 인터페이스를 구현하는 새로운 클래스를 작성하여 새로운 로직을 작성하는 것이다
  3. 자바 8에 추가된 default 메소드에 대해 설명하세요 : default 메소드는 인터페이스를 상속받는 모든 클래스에 공통으로 사용할 함수를 작성할 때 사용하며 하위 클래스는 해당 함수를 그대로 사용할 수 있고 오버라이딩도 가능하다

 

코딩으로 학습하는 GoF의 디자인 패턴 - 인프런 | 강의

디자인 패턴을 알고 있다면 스프링 뿐 아니라 여러 다양한 기술 및 프로그래밍 언어도 보다 쉽게 학습할 수 있습니다. 또한, 보다 유연하고 재사용성이 뛰어난 객체 지향 소프트웨어를 개발할

www.inflearn.com

 

'java' 카테고리의 다른 글

Design Patterns - Builder  (0) 2021.11.21
Design Patterns - Abstract Factory  (0) 2021.11.20
Design Patterns - Singleton  (0) 2021.11.11
함수형 인터페이스를 이용한 Builder  (0) 2021.05.29
더 자바(java 8) - CompletableFuture  (0) 2021.05.26

댓글