COPY - https://blog.seotory.com/post/2016/08/java-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); }}
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는 비슷한 구조를 가진다.
이제 클라이언트 클래스에서 sub-class 생성 시점을 제공해주는 사용 클래스를 만들어보자.
public class ProductFactory { public static Product getProduct(ProductAbstractFactory productFactory) { 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() ); }}
추상 팩토리 클래스 패턴은 인터페이스 보다는 구조체에 접근할 수 있는 코드를 제공한다.
추상 팩토리 클래스 패턴은 확장에 매우 용의한 패턴으로 쉽게 다른 서브 클래스들을 확장할 수 있다.
추상 팩토리 클래스 패턴은 기존 팩토리 패턴의 if-else 로직에서 벗어날 수 있게 해준다.
위의 클래스들을 보기 쉽게 UML로 그려보면 아래와 같을 것이다.