[Design Pattern] 추상 팩토리 패턴(Abstract Factory Pattern)
Posted: Updated:
자바 디자인 패턴 스터디를 하며 ‘Java 객체 지향 디자인 패턴’ 교재를 정리한 글입니다.
추상 팩토리 패턴(Abstract Factory Pattern)
- 관련성 있는 여러 종류의 객체를 일관된 방식으로 생성
- 서로 연관되거나 의존적인 객체들의 조합을 만듦
추상 팩토리 패턴 컬레보레이션
- AbstractFactory
- 실제 팩토리 클래스의 공통 인터페이스
- 각 제품의 부품을 생성하는 기능을 추상 메서드로 정의
- ConcreteFactory
- 구체적인 팩토리 클래스
AbstractFactory
클래스의 추상 메서드를 오버라이드- 구체적인 제품 생성
- AbstractProduct
- 제품의 공통 인터페이스
- ConcreteProduct
- 구체적인 팩토리 클래스에서 생성되는 구체적인 제품
예시: 엘리베이터 부품 업체 변경하기
- 엘리베이터마다 다른 제조 업체의 부품을 사용할 때 프로그램 변경 최소화
전체 코드
public enum Direction {
UP, DOWN
}
public enum DoorStatus {
OPENED, CLOSED
}
public enum MotorStatus {
MOVING, STOPPED
}
public enum VendorID {
LG, HYUNDAI
}
public abstract class DirectionLamp {
private Direction lampStatus;
public void light(Direction direction) {
if (lampStatus == getLampStatus()) {
return;
}
doLight(lampStatus);
setLampStatus(lampStatus);
}
private Direction getLampStatus() {
return lampStatus;
}
private void setLampStatus(Direction lampStatus) {
this.lampStatus = lampStatus;
}
protected abstract void doLight(Direction lampStatus);
}
public abstract class Door {
private DoorStatus doorStatus;
public Door() {
this.doorStatus = DoorStatus.OPENED;
}
public DoorStatus getDoorStatus() {
return doorStatus;
}
public void close() {
if (doorStatus == DoorStatus.CLOSED) {
return;
}
doClose();
doorStatus = DoorStatus.CLOSED;
}
protected abstract void doClose();
public void open() {
if (doorStatus == DoorStatus.OPENED) {
return;
}
doOpen();
doorStatus = DoorStatus.OPENED;
}
protected abstract void doOpen();
}
public class DoorFactory {
public static Door createDoor(VendorID vendorID) {
Door door = null;
switch (vendorID) {
case LG: door = new LgDoor(); break;
case HYUNDAI: door = new HyundaiDoor(); break;
}
return door;
}
}
public class Elevator {
private Motor motor;
private Door door;
private DirectionLamp lamp;
public void setLamp(DirectionLamp lamp) {
this.lamp = lamp;
}
public void setMotor(Motor motor) {
this.motor = motor;
}
public void setDoor(Door door) {
this.door = door;
}
public void move(Direction direction) {
motor.move(direction);
lamp.doLight(direction);
}
}
public class ElevatorCreator {
public static Elevator assembleElevator(ElevatorFactory factory) {
Elevator elevator = factory.createElevator();
Motor motor = factory.createMotor();
elevator.setMotor(motor);
Door door = factory.createDoor();
elevator.setDoor(door);
motor.setDoor(door);
DirectionLamp lamp = factory.createLamp();
elevator.setLamp(lamp);
return elevator;
}
}
public abstract class ElevatorFactory {
public abstract Elevator createElevator();
public abstract Motor createMotor();
public abstract Door createDoor();
public abstract DirectionLamp createLamp();
}
public class HyundaiElevator extends Elevator {
}
public class HyundaiDoor extends Door{
@Override
protected void doClose() {
System.out.println("Close Hyundai Door");
}
@Override
protected void doOpen() {
System.out.println("Open Hyundai Door");
}
}
public class HyundaiElevatorFactory extends ElevatorFactory{
@Override
public Elevator createElevator() {
return new HyundaiElevator();
}
@Override
public Motor createMotor() {
return new HyundaiMotor();
}
@Override
public Door createDoor() {
return new HyundaiDoor();
}
@Override
public DirectionLamp createLamp() {
return new HyundaiLamp();
}
}
public class HyundaiLamp extends DirectionLamp{
@Override
protected void doLight(Direction direction) {
System.out.println("Hyundai Lamp "+direction);
}
}
public class HyundaiMotor extends Motor{
@Override
protected void moveMotor(Direction direction) {
System.out.println("Hyundai motor is Moving "+direction);
}
}
public class LampFactory {
public static DirectionLamp createLamp(VendorID vendorID) {
DirectionLamp lamp = null;
switch (vendorID) {
case LG: lamp = new LgLamp(); break;
case HYUNDAI: lamp = new HyundaiLamp(); break;
}
return lamp;
}
}
public class LgDoor extends Door{
@Override
protected void doClose() {
System.out.println("Close Lg Door");
}
@Override
protected void doOpen() {
System.out.println("Open Lg Door");
}
}
public class LgElevator extends Elevator {
}
public class LgElevatorFactory extends ElevatorFactory{
@Override
public Elevator createElevator() {
return new LgElevator();
}
@Override
public Motor createMotor() {
return new LgMotor();
}
@Override
public Door createDoor() {
return new LgDoor();
}
@Override
public DirectionLamp createLamp() {
return new LgLamp();
}
}
public class LgLamp extends DirectionLamp{
@Override
protected void doLight(Direction direction) {
System.out.println("Lg Lamp "+direction);
}
}
public class LgMotor extends Motor{
@Override
protected void moveMotor(Direction direction) {
System.out.println("Lg motor is Moving "+direction);
}
}
public abstract class Motor {
private Door door;
private MotorStatus motorStatus;
public void setDoor(Door door) {
this.door = door;
this.motorStatus = MotorStatus.STOPPED;
}
public void move(Direction direction) {
MotorStatus motorStatus = getMotorStatus();
if (motorStatus == MotorStatus.MOVING) {
return;
}
DoorStatus doorStatus = door.getDoorStatus();
if (doorStatus == DoorStatus.OPENED) {
door.close();
}
moveMotor(direction);
setMotorStatus(MotorStatus.MOVING);
}
private void setMotorStatus(MotorStatus motorStatus) {
this.motorStatus = motorStatus;
}
protected abstract void moveMotor(Direction direction);
private MotorStatus getMotorStatus() {
return motorStatus;
}
}
public class MotorFactory {
public static Motor createMotor(VendorID vendorID) {
Motor motor = null;
switch (vendorID) {
case LG: motor = new LgMotor(); break;
case HYUNDAI: motor = new HyundaiMotor(); break;
}
return motor;
}
}
public class Main {
public static void main(String[] args) {
ElevatorFactory factory = null;
String vendorName = "LG";
if (vendorName.equalsIgnoreCase("LG")) {
factory = new LgElevatorFactory();
}
else {
factory = new HyundaiElevatorFactory();
}
Elevator elevator = ElevatorCreator.assembleElevator(factory);
elevator.move(Direction.UP);
}
}
출력
Close Lg Door
Lg motor is Moving UP
Lg Lamp UP
댓글남기기