추상 팩토리 패턴(1) - 개념, 패턴 적용하기
1) 추상 팩토리 패턴이란?
- 추상 팩토리는 관련 있는 여러 인스턴스를 만들어주는 팩토리를 추상화된 형태로 정의하는 패턴입니다.
그래서 구체적인 팩토리에서 구체적인 인스턴스를 만드는 것까지는 팩토리 메소드 패턴과 매우 비슷하지만,
초점이 클라이언트 쪽에 있습니다.
- 추상 팩토리 패턴의 목적 자체가 클라이언트 코드를 인터페이스 기반으로 할 수 있게끔 도와주는 것입니다.
모양은 팩토리 쪽에서 보면 팩토리 메소드 패턴과 매우 비슷하지만,
팩토리를 사용하는 쪽 코드와 같이 봐야 합니다.
- 이전에 살펴봤던 패턴에 비해 클라이언트만 추가되었고,
내부 구조는 팩토리 메소드 패턴과 매우 비슷합니다.
2) 패턴 적용하기
- 이 클래스는 클라이언트 코드에 해당합니다.
클라이언트 코드를 보면 구체적인 클래스 타입(ex) new WhiteAnchor(), new WhiteWheel())
에 의존하고 있음을 볼 수 있습니다.
이 때, 할 일은 비슷한 류의 제품군을 만드는 인터페이스를 정의하는 것입니다.
public class WhiteshipFactory extends DefaultShipFactory{
@Oveerride
public Ship createShip(){
Ship ship = new Whiteship();
ship.setAnchor(new WhiteAnchor());
ship.setWheel(new WhiteWheel());
return ship;
}
}
- ShipPartsFactory라는 추상 팩토리를 만들 수 있습니다.
Anchor와 Wheel도 각각 인터페이스를 만들었습니다.
public interface ShipPartsFactory {
Anchor createAnchor();
Wheel createWheel();
}
public interface Anchor{
}
public interface Wheel{
}
- 그리고 추상 팩토리의 구체적인 팩토리인 WhiteshipPartsFactory를 만들 수 있습니다.
public class WhiteshipPartsFactory implements ShipPartsFactory{
@Override
public Anchor createAnchor(){
return new WhiteAnchor();
}
@Override
public Wheel createWheel(){
return new WhiteWheel();
}
}
- WhiteAnchor와 WhiteWheel은 각각의 제품군에 해당하는 인터페이스를 구현해야 합니다.
그래야만 그 제품의 특징을 가질 수 있습니다.
public class WhiteAnchor implements Anchor{
}
public class WhiteWheel implements Wheel{
}
- 그 다음 ShipPartsFactory를 주입 받아서, Anchor와 Wheel을 생성해줍니다.
public class WhiteshipFactory extends DefaultShipFactory{
private ShipPartsFactory shipPartsFactory;
public WhiteshipFactory(ShipPartsFactory shipPartsFactory){
this.shipPartsFactory = shipPartsFactory;
}
@Oveerride
public Ship createShip(){
Ship ship = new Whiteship();
ship.setAnchor(shipPartsFactory.createAnchor());
ship.setWheel(shipPartsFactory.createWheel());
return ship;
}
}
- 이제 Pro 제품을 만들고 싶다면 다음과 같이 하면 됩니다.
public class WhitePartsProFactory implements ShipPartsFactory{
@Override
public Anchor createAnchor(){
return new WhiteAnchorPro();
}
@Override
public Anchor createWheel(){
return new WhieWheelPro();
}
}
public WhiteAnchorPro implements Anchor{
}
public WhiteWheelPro implements Wheel{
}
- 이제 ShipInventory에서 ShipFactory를 WhitePartsProFactory를 통해서 만들 수 있습니다.
혹은 WhitePartsProFactory를 WhiteshipPartsFactory로 교체할 수도 있습니다.
이 때, WhiteshipFactory 자체는 바뀌지 않습니다.
public class ShipInventory{
public static void main(String[] args){
ShipFactory shipFactory = new WhiteshipFactory(new WhitePartsProFactory());
Ship ship = shipFactory.createShip();
System.out.println(ship.getAnchor().getClass());
System.out.println(ship.getWheel().getClass());
}
}
- 이 때, ShipPartsFactory는 일종의 SRP를 지켰다고 볼 수도 있지만,
또 다른 관점으로는 여러 가지 제품을 받으므로 SRP를 위반한거 아니냐라고 볼 수도 있습니다.
혹은 WhiteshipFactory가 OCP를 지켰다고 볼 수도 있습니다.
참고
- 백기선 코딩으로 학습하는 GoF의 디자인 패턴