프로그래밍/디자인패턴

디자인 패턴 - Abstract Factory (Creational Pattern)

aiemag 2021. 2. 26. 17:44
반응형

Creational Pattern인 Abstract Factory Pattern에 대해 정리합니다.

 

 


Definition

 

Abstract Factory 는 추상적인 공장에서 추상적인 부품을 조합해서 제품을 만드는 패턴입니다.

 

부품의 구체적인 구현에는 주목하지 않고 abstract class의 interface에 주목하여 부품을 조립합니다.

 


Class Diagram

factory package의 AbstractFactory는 AbstractProduct1, AbstractProduct2를 만듭니다.

 

factory package의 내용을 바탕으로 concretefactory pacakage에서 구현을 실체화 합니다.

 

Abstract Factory 및 Product의 형태 기반에서 비슷하지만 다양한 형태의 Factory 및 Product을 구현하여 사용할 수 있습니다.

 


Sample Case

다음은 Factory Method 패턴을 적용한 시나리오입니다.

 

Scenario

우리는 자동차(Car) 공장(Factory)을 만드는데, 취급하는 종류는 슈퍼카(SuperCar)와 4륜구동차량(FourWheelDriveCar)입니다.

 

모든 종류의 차량에는 가속(accelerate())기능과 감속(decelerate())기능이 있고 기본 차량 id가 존재합니다.

슈퍼카에는 좀 더 가속 가능한 부스터(boost())기능이 있고, 4륜구동차량에는 4개휠을 사용할 수 있는 기어작동모드(operateGear())가 있습니다.

 

슈퍼카와 4륜구동차량 모두 모델 이름(name) 정보가 있고, 슈퍼카에는 특별히 라이센스(license) 정보가 요구됩니다.

 

공장(Factory)에서는 슈퍼카와, 4륜구동차량을 만들 수 있습니다.

 

※ 사업이 잘되면 나중에는 추가로 세단차량과 소형차량도 만들 계획입니다.

   또한, 일반차량 뿐만 아니라, 유모차 시장도 진출할 계획입니다. 

   해당 abstract factory package를 바탕으로 이를 대응할 수 있을 것 같습니다.

Class Diagram

 

 

Code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import factory.Factory;
import factory.FourWheelDriveCar;
import factory.SuperCar;
 
public class Main {
    
    public static void main(String[] args) {
        
        Factory factory = Factory.getFactory("carfactory.CarFactory");
        
        SuperCar boxster = factory.createSuperCar(100"Boxster""F-1");
        FourWheelDriveCar cayenne = factory.createFourWheelDriveCar(200"Cayenne");
                
        boxster.accelerate();
        boxster.boost();
        boxster.decelerate();
        
        cayenne.accelerate();
        cayenne.operateGear();
        cayenne.decelerate();
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
package factory;
 
public abstract class Car {
    protected int id;
    
    public Car(int id) {
        this.id = id;
    }
    
    public abstract void accelerate();
    public abstract void decelerate();
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package factory;
 
public abstract class SuperCar extends Car{    
    protected String name; 
    protected String license;
    
    public SuperCar(int id, String name, String license) {
        super(id);
        this.name = name;        
        this.license = license;
    }
    
    public void boost() {
        System.out.println(this+" Boost On ***");
    }
    
    public String toString() {
        return "\"ID : " + this.id + ", NAME : " + this.name + 
                ", LICENSE : "+this.license + "\"";
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package factory;
 
public abstract class FourWheelDriveCar extends Car{
    protected String name;
    
    public FourWheelDriveCar(int id, String name) {
        super(id);
        this.name = name;
    }
    
    public void operateGear() {
        System.out.println(this+" 4 Wheels On ***");
    }
    
    public String toString() {
        return "\"ID : " + this.id + ", NAME : " + this.name + "\"";
    }
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package factory;
 
public abstract class Factory {
    
    public static Factory getFactory(String classname) {
        Factory factory = null;
        try {
            factory = (Factory)Class.forName(classname).newInstance();
        }catch(ClassNotFoundException e) {
            System.out.println(classname + " is not found.");
        }catch(Exception e) {
            e.printStackTrace();
        }
        
        return factory;
    }
 
    public abstract SuperCar createSuperCar(int id, String name, String license);
    public abstract FourWheelDriveCar createFourWheelDriveCar(int id, String name);
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package carfactory;
 
import factory.SuperCar;
 
public class SportsCar extends SuperCar{
    
    public SportsCar(int id, String name, String license) {
        super(id, name, license);
    }
    
    public void accelerate() {
        System.out.println(this + " is accelerating.");
    }
 
    public void decelerate() {
        System.out.println(this + " is decelerating.");
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package carfactory;
 
import factory.FourWheelDriveCar;
 
public class Suv extends FourWheelDriveCar{
    
    public Suv(int id, String name) {
        super(id, name);
    }
    
    public void accelerate() {
        System.out.println(this + " is accelerating.");
    }
 
    public void decelerate() {
        System.out.println(this + " is decelerating.");
    }
}
 
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package carfactory;
 
import factory.Factory;
import factory.FourWheelDriveCar;
import factory.SuperCar;
 
public class CarFactory extends Factory{
 
    public SuperCar createSuperCar(int id, String name, String license) {
        return new SportsCar(id, name, license);
    }
 
    public FourWheelDriveCar createFourWheelDriveCar(int id, String name) {
        return new Suv(id, name);
    }
}
cs

 

실행 결과

반응형