abstract factory pattern은 생산적인 디자인 패턴 중 하나로써 좀 더 factory를 좀 더 생산적으로 만들어 낼 수 있다는 점외에는 factory pattern과 매우 비슷하다.

여러분이 java의 factory design pattern에 익숙하다면, 보통은 어떠한 인풋에 대해 factory class안에서 if-else로 다른 sub-class를 반환하는 일련의 과정을 통해 목적을 달성할 것이다.

abstract factory pattern에서는 if-else 구문을 없애고, sub-class마다 factory class를 가지게 하고 Abstract Factory에서는 input factory class를 통해 해당 sub-class를 반환한다. 처음보기에는 factory pattern 과 혼동되지만, 구현된 것을 보면 정말 쉽게 factory pattern과 abstract factory pattern의 차이점을 할 수 있을것이다.

슈퍼 클래스와 서브 클래스

이번 포스트에서 전에 사용했던 product, ticket, computer 클래스를 똑같이 사용한다.

public abstract class Product {
    public abstract String getName();
    public abstract int getPrice();

    @Override
    public String toString() {
        return "product name : " + getName() + ", price :" + getPrice();
    }
}
public class Computer extends Product {
    private String name;
    private int price;

    public Computer (String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String getName() {
        return this.name;
    }
    @Override
    public int getPrice() {
        return this.price;
    }
}
public class Ticket extends Product {
    private String name;
    private int price;

    public Ticket (String name, int price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String getName() {
        return this.name;
    }
    @Override
    public int getPrice () {
        return this.price;
    }
}

팩토리 클랙스마다 각각의 서브 클래스

먼저 abstract factory interface(또는 abstract)가 필요하다.

public interface ProductAbstractFactory {
    public Product createProduct();
}

createProduct() method 는 super class 격인 Product 인스턴스를 반환한다. 이제 ProductAbstractFactory 인터페이스와 각각의 sub-class를 구현해보자.

sub-class를 위한 factory class를 아래와 같이 비슷하게 만들것이다.

public class ComputerFactory implements ProductAbstractFactory {
    private String name;
    private int price;
    public ComputerFactory(String name, int price) {
        this.name = name;
        this.price = price;
    }
    public Product createProduct() {
        return new Computer(name, price);
    }
}

각각의 sub-class는 비슷한 구조를 가진다.

public class TicketFactory implements ProductAbstractFactory {
    private String name;
    private int price;

    public TicketFactory (String name, int price) {
        this.name = name;
        this.price = price;
    }

    public Product createProduct() {
        return new Ticket(name, price);
    }
}

사용 클래스

이제 클라이언트 클래스에서 sub-class 생성 시점을 제공해주는 사용 클래스를 만들어보자.

public class ProductFactory {
    public static Product getProduct(ProductAbstractFactory product) {
        return product.createProduct();
    }
}

위의 클래스는 간단한 클래스이다. getComputer method는 인자로 Computer AbstractFactory를 받고 Product object 를 반환한다. 바로 이곳이 object 구현을 매우 깔끔하게 하는 중요한 포인트지점이다.

테스트 클래스

이제 테스트를 위한 class를 아래와 같이이 만들어보자.

public class main {
    public static void main(String[] args) {
        Product com = ProductFactory.getProduct(new ComputerFactory("com1", 2000));
        Product tk = ProductFactory.getProduct(new TicketFactory("공연", 100000));
        System.out.println( com.toString() );
        System.out.println( tk.toString() );
    }
}

abstract factory pattern 사용 장점

  • 추상 팩토리 클래스 패턴은 인터페이스 보다는 구조체에 접근할 수 있는 코드를 제공한다.
  • 추상 팩토리 클래스 패턴은 확장에 매우 용의한 패턴으로 쉽게 다른 서브 클래스들을 확장할 수 있다.
  • 추상 팩토리 클래스 패턴은 기존 팩토리 패턴의 if-else 로직에서 벗어날 수 있게 해준다.

UML - class 다이어그램

위의 클래스들을 보기 쉽게 UML로 그려보면 아래와 같을 것이다.

UML

Tags : java pattern

java proxy pattern (프록시 패턴)

프록시는 실제로 액션을 취하는 객체를 대신해서 대리자 역할을 해준다. 프록시 패턴을 사용하게 되면 프록시 단계에서 권한을 부여할 수 있는 이점이 생기고 필요에 따라 객체를 생성시키거나 사용하기 때문에 메모리를 절약할 수 있는 이점도 생긴다. 프록시 패턴이 하는 일은 한마디로 자신이 보호하고...

더보기

java composite pattern (컴포지트 패턴)

컴포지트 패턴이란 클래스의 구조적 디자인 패턴으로 단일 객체와 복합 객체를 동일하게 컨트롤 할 수 있게끔 도와주는 패턴이다. 컴포지트 패턴은 아래와 같이 3가지의 요소에 의해 이루어진다. base component base component는 composition(구성자)을 위한 인터페이스로 구성된다. 클라이언트 클래스에서는 base component의 인터페이스를 사용하여 작업하게...

더보기

java adapter pattern (어뎁터 패턴)

adapter pattern은 관계가 없는 인터페이스들이 같이 일할 수 있도록 도와주는 디자인 패턴이다. 이 두 인터페이스를 이어주는 인터페이스를 adapter라 부른다. 아래 예제를 보면서 이해해보도록하자. volt class public class Volt { private int volts; public Volt(int v) { this.volts = v; }...

더보기

java builder pattern (빌더 패턴)

bulider pattern은 창조적 디자인 패턴이며 이것은 factory pattern 또는 abstract factory pattern과 매우 비슷하다. 이 패턴에 들어가기 전에 factory pattern과 abstract factory pattern들의 문제점(수 많은 attributes을 사용해야 패턴을 사용할 수 있는 점)에 대해 먼저 알아보자. factory pattern과 abstract factory pattern에는...

더보기