티스토리 뷰

728x90
반응형

추상 팩토리 패턴이란?


  • 서로 관련성 있는 객체들을 인터페이스로 규격화하여 팩토리에서 일정한 방식으로 생성하는 패턴입니다.
  • 구체적으로 어떤 클래스의 인스턴스를 사용하는지 감출 수 있습니다.
  • 팩토리 메서드 패턴과 굉장히 유사하지만 초점은 클라이언트에게 있다고 생각하시면 됩니다. 추상 팩토리 패턴 목적 차제가 클라이언트 코드에서 인스턴스를 만들어서 쓰는 코드를 인터페이스 기반으로 코딩을 할 수 있게끔 도와주는 패턴입니다.

 

추상 팩토리 구조


 

클래스 다이어그램


 

추상 팩토리 패턴을 사용한 예제 1)


💡Abstract Factory와 Concrete Factory

// 추상 팩토리 
public interface ShipFactory {

    Anchor createAnchor();

    Wheel createWheel();
}

// 실제 객체를 반환하는 팩토리
public class DefaultFactory implements ShipFactory {

    @Override
    public Anchor createAnchor() {
        return new WhiteAnchor();
    }

    @Override
    public Wheel createWheel() {
        return new WhiteWheel();
    }
}

// 실제 객체를 반환하는 팩토리
public class ProFactory implements ShipFactory {

    @Override
    public Anchor createAnchor() {
        return new WhiteAnchorPro();
    }

    @Override
    public Wheel createWheel() {
        return new WhiteWheelPro();
    }
}

 

💡Abstract Product와 Concrete Product

// 추상 제품군
public interface Anchor {

}

// 구체화된 제품군
public class WhiteAnchor implements Anchor {

}

// 구체화된 제품군
public class WhiteAnchorPro implements Anchor {

}

// 추상 제품군
public interface Wheel {

}

// 구체화된 제품군
public class WhiteWheel implements Wheel {

}

// 구체화된 제품군
public class WhiteWheelPro implements Wheel {

}

 

💡생성되는 아이템

// 생성되는 아이템
@Getter
@Setter
@ToString
public class Ship {

    private String name;
    private String color;
    private Anchor anchor;
    private Wheel wheel;

    public void setAnchor(Anchor anchor) {
        this.anchor = anchor;
    }

    public void setWheel(Wheel wheel) {
        this.wheel = wheel;
    }
}

 

💡생성하는 팩토리

// 객체를 생성하고 반환하는 팩토리
public class CreatorFactory {

    private final ShipFactory shipFactory;

    public CreatorFactory(ShipFactory shipFactory) {
        this.shipFactory = shipFactory;
    }

    public Ship createShip() {
        Ship ship = new Ship();
        ship.setAnchor(shipFactory.createAnchor());
        ship.setWheel(shipFactory.createWheel());
        return ship;
    }
}

 

💡클라이언트

public class Client {
    public static void main(String[] args) {

        CreatorFactory proFactory = new CreatorFactory(new ProFactory());
        Ship proShip = proFactory.createShip();
        System.out.println(proShip.getWheel().getClass());
        System.out.println(proShip.getAnchor().getClass());

        CreatorFactory defaultFactory = new CreatorFactory(new DefaultFactory());
        Ship defaultShip = defaultFactory.createShip();
        System.out.println(defaultShip.getWheel().getClass());
        System.out.println(defaultShip.getAnchor().getClass());
    }
}

 

 

추상 팩토리 패턴을 사용한 예제 2)


아래는 필자의 생각대로 만든 예제입니다.

 

💡Abstract Factory와 Concrete Factory

// Abstract Factory
public interface PhoneFactory {

    Phone createPhone();
}

// Concrete Factory
public class AppleFactory implements PhoneFactory {

    @Override
    public Phone createPhone() {
        return new ApplePhone();
    }
}

// Concrete Factory
public class SamsungFactory implements PhoneFactory {

    @Override
    public Phone createPhone() {
        return new SamsungPhone();
    }
}

 

💡Abstract Product

// Abstract Product들
public interface Company {

    void name();
}

public interface Battery {

    void power();
}

public interface Camera {

    void power();
}

 

💡Concrete Product

// Concrete Product들
public class AppleCompany implements Company {

    @Override
    public void name() {
        System.out.println("Apple");
    }
}

public class AppleCamera implements Camera {

    @Override
    public void power() {
        System.out.println("AppleCamera 성능");
    }
}

public class AppleBattery implements Battery {

    @Override
    public void power() {
        System.out.println("AppleBattery 성능");
    }
}

---------------------------------------------------------------------

public class SamsungCompany implements Company {

    @Override
    public void name() {
        System.out.println("Samsung");
    }
}

public class SamsungCamera implements Camera {

    @Override
    public void power() {
        System.out.println("SamsungCamera 성능");
    }
}

public class SamsungBattery implements Battery {

    @Override
    public void power() {
        System.out.println("SamsungBattery 성능");
    }
}

 

💡생성 아이템

@Setter
@Getter
@ToString
public abstract class Phone {

    private Company company;
    private Battery battery;
    private Camera camera;
}

public class ApplePhone extends Phone {

}

public class SamsungPhone extends Phone {

}

 

💡생성하는 팩토리

public class Person {

    private final PhoneFactory phoneFactory;

    public Person(PhoneFactory phoneFactory) {
        this.phoneFactory = phoneFactory;
    }

    public Phone buy(PersonType personType) {
        Phone phone = null;

        if (PersonType.TEACHER == personType) {
            phone = new ApplePhone();
            phone.setCompany(new AppleCompany());
            phone.setBattery(new AppleBattery());
            phone.setCamera(new AppleCamera());
        }
        if (PersonType.STUDENT == personType) {
            phone = new SamsungPhone();
            phone.setCompany(new SamsungCompany());
            phone.setBattery(new SamsungBattery());
            phone.setCamera(new SamsungCamera());
        }
        return phone;
    }
}

public enum PersonType {

    TEACHER,
    STUDENT
}

 

💡클라이언트

public class Client {
    public static void main(String[] args) {
        Person teacher = new Person(new AppleFactory());
        Phone phone1 = teacher.buy(PersonType.TEACHER);
        System.out.println(phone1.getCompany().getClass());
        System.out.println(phone1.getBattery().getClass());
        System.out.println(phone1.getCamera().getClass());

        Person student = new Person(new SamsungFactory());
        Phone phone2 = student.buy(PersonType.STUDENT);
        System.out.println(phone2.getCompany().getClass());
        System.out.println(phone2.getBattery().getClass());
        System.out.println(phone2.getCamera().getClass());
    }
}

 

 

추상 팩토리 패턴의 장단점


💡 장점

  • 확장성이 있습니다.
  • 느슨한 결합을 이룰 수 있습니다.

💡 단점

  • 객체가 늘어날때마다 하위 클래스를 재정의 해줘야하므로 너무 많은 클래스를 만들게 됩니다.

 

💡 추상 팩토리 메서드 패턴과 팩토리 메서드 패턴의 차이

  • 팩토리 메서드 패턴은 구체적인 인스턴스 생성 과정을 하위 클래스에게 위임하는게 목적입니다.
  • 추상 팩토리 패턴은 관련있는 여러 객체를 구체적인 클래스에 의존하지 않고 생성할 수 있도록 해주는 것이 목적입니다.

 

 

 

728x90
반응형