본문으로 바로가기
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



팩토리는 공장을 의미한다. 공장은 물건을 생산하는데 객체 지향에서 팩터리는 객체를 생성하는 것을 의미한다. 즉 다시말해서 팩토리 메서드는 객체를 생성 반환하는 메서드를 말한다. 여기에서 패턴이 붙으면 하위 클래스에서 팩터리 메서드를 오버라이딩해서 객체를 반환하게 하는 것을 의미한다. 왜 팩토리 메소드를 사용하냐면 클래스간의 결합도를 낮추기 위해서이다. 팩토리 메소드를 사용하게 되면 직접 클래스를 생성 및 사용하는 것을 방지하고 서브 클래스에 위임하여 보다 효율적인 코드 제어를 할 수 있고, 의존성을 제거할 수 있어 결합도를 낮출 수 있다.


위의 설명을 토대로 설명을 위해 "로봇"과 "로봇을 만들어 내는 공장"을 예로 들어 설명을 하겠다.


로봇 공장이 있다. 로봇 공장에는 태권V로봇, 다간, 그리고 귀여운 뽀로로 3가지의 로봇이 있다. 팩토리에서 만들어내는 객체를 정의하기 위해 추상클래스인 Robot과 Robot을 상속 받은 태권V, 다간, 뽀로로 클래스를 선언한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
abstract class Robot {
    public abstract String getName();
    
    public String attack() {
        
        return "주먹 펀치!!";
    }
}
 
class TaekwonV extends Robot {
    
    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return "태권V!!!";
    }
    
}
 
class Dagan extends Robot {
 
    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return "다간!!!";
    }
    
    @Override
    public String attack() {
        
        return "발차기!!";
    }
}
 
class Pororo extends Robot {
 
    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return "뽀로로 ><";
    }
    
    @Override
    public String attack() {
        
        return "애교 공격";
    }
}



이제 태권V, 다간, 뽀로로 로봇을 만들기 위한 "팩토리" 즉 공장을 만들어 보자.

로봇을 만들어 내는 공장은 2개가 있다. 공장 2개의 이름은 MakeRobot과 CreateRobot이다. 두 공장은 같은 구현 동작을 보장하기 위해 RobotFactory라는 추상클래스를 상속 받았다. 두 공장의 차이는 약간? 구현이 다르다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
abstract class RobotFactory {
    abstract Robot makeRobot(String name);
}
 
class MakeRobot extends RobotFactory {
 
    @Override
    Robot makeRobot(String name) {
        // TODO Auto-generated method stub
        
        switch(name) {
            case "taekwonV"return new TaekwonV();
            case "dagan"return new Dagan();
            case "pororo"return new Pororo();
        }
        
        return null;
    }
}
 
class CreateRobot extends RobotFactory {
 
    @Override
    Robot makeRobot(String name) {
        // TODO Auto-generated method stub
        
        try {
            Class<?> cls = Class.forName(name);
            Object obj = cls.newInstance();
            
            return (Robot)obj;
            
        } catch (Exception e) {
            e.printStackTrace();
        }
        
        return null;
    }
}



실행 결과를 보면 아래와 같다. main 메서드에서 new 키워드 없이 로봇을 생성할 수 있음을 알 수 있다. RobotFactory라는 추상클래스를 상속받은 공장들에게서 만들어진 객체를 사용하기 때문이다. 그리고 추상클래스인 Robot을 상속받는다면 새로운 로봇이 추가되도 쉽게 공장에서 만들어 낼 수 있다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public static void main(String[] args) {
    RobotFactory rf = new MakeRobot();
    
    Robot taekwonV = rf.makeRobot("taekwonV");
    //태권V!!! 주먹 펀치!!
    System.out.println(taekwonV.getName() + " " + taekwonV.attack());
    
    Robot dagan = rf.makeRobot("dagan");
    //다간!!! 발차기!!
    System.out.println(dagan.getName() + " " + dagan.attack());
    
    Robot pororo = rf.makeRobot("pororo");
    //뽀로로 >< 애교 공격
    System.out.println(pororo.getName() + " " + pororo.attack());
    
    
    RobotFactory rf2 = new CreateRobot();
    
    Robot taekwonV2 = rf2.makeRobot("com.ktko.factorypattern.TaekwonV");
    System.out.println(taekwonV2.getName() + " " + taekwonV2.attack());
    
}



팩토리 메서드 패턴을 요약하자면 "오버라이드된 메서드가 객체를 반환하는 패턴" 이라고 할 수 있다. 코드와 설명을 보면 팩토리 메서드 패턴은 의존 역전 원칙(DIP)을 활용하고 있음을 알 수 있다.