2014. 4. 25. 14:41



출저:  http://iilii.egloos.com/3791596



자바 디자인 패턴 3Factory Method


1. Factory Method패턴은..


factory는 공장이죠. 객체를 막 찍어내는 놈입니다. 객체 선언은 보통 new 객체() 이런식으로 하죠. factory는 내부에서 그런 일을 해줍니다. 즉 factory를 가져다가 쓰는 부분에서는 new 객체()와 같은 식으로 변수를 선언할 필요가 없습니다.Abstract class나 인터페이스에 대해서 다양한 하위 구현체가 있을 경우에 사용하면 좋습니다. 사용법은 Factory.create(인자는 맘대로) 와 같이 됩니다. 


2. 예제


package chap03_StaticFactory;

public interface Animal {

    public void printDescription();

}



package chap03_StaticFactory;

public class AnimalFactory {

    public static Animal create(String animalName){

        if (animalName == null) {

            throw new IllegalArgumentException("null은 안 되지롱~");

        }

        if (animalName.equals("소")) {

            return new Cow();

        }else if (animalName.equals("고양이")) {

            return new Cat();

        }else if (animalName.equals("개")) {

            return new Dog();

        }else{

            return null;

        }

    }

}



package chap03_StaticFactory;

public class Cat implements Animal {

    public void printDescription() {

        System.out.println("쥐잡기 선수");

    }

}



package chap03_StaticFactory;

public class Cow implements Animal {

    public void printDescription() {

        System.out.println("우유 및 고기 제공");

    }

}



package chap03_StaticFactory;

public class Dog implements Animal {

    public void printDescription() {

        System.out.println("주로 집 지킴");

    }

}



package chap03_StaticFactory;

public class Test {

    public static void main(String[] args) {

        Animal a1= AnimalFactory.create("소");

        a1.printDescription();

        Animal a2= AnimalFactory.create("고양이");

        a2.printDescription();

        Animal a3= AnimalFactory.create("개");

        a3.printDescription();

    }

}


이번 것은 소스가 좀 깁니다. 일단 Animal이라는 인터페이스가 있습니다. Cat, Cow, Dog 는 이 인터페이스의 구현체들입니다.

그리고 AnimalFactory가 있는데, 여기서 Animal의 구현체를 돌려줍니다.

Test에서 new Cow()와 같이 하지 않고, AnimalFactory.create("소")를 호출하는 게 일반적인 방법과의 차이입니다.

Animal의 구현체가 더 늘어나면 어떻게 될까요? 전부 new AnotherAnimal()과 같이 생성하는 것보다는 Facotry의 create()메쏘드만 수정하는 게 좀 편하겠죠? 


3. Factory 의 유용성


Animal a1 = AnimalFactory.create("소"); 와 같은 코드에서 a1이 Cow라는 것을 굳이 신경쓰지 않겠다는 겁니다. Test클래스 안에는 new 라는 구문 자체가 없습니다. 정확히 어떤 클래스의 인스턴스인지 신경쓰지 않고 구현할 수 있는 장점이 있습니다. 객체 타입이 굉장히 유연해 질 수 있죠.


4. JAVA API에 있는 Factory Method


Factory 패턴의 중요한 특징 중 하나는 Factory에서 리턴할 때는 매번 객체를 새로 만들지 않을 수도 있다는 겁니다.

Boolean.valueOf(boolean) 을 먼저 살펴 보죠. 

        Boolean a = Boolean.valueOf(true);

        Boolean b = Boolean.valueOf(true);

        System.out.println(a==b);

이 코드를 실행시키면 어떤 결과가 나올까요? true 가 나옵니다. 왜냐하면  Boolean.valueOf(true) 는 Boolean.TRUE 라는 상수를 리턴합니다. 즉, 인스턴스를 새로 만드는 것이 아니라 기존에 있는 것을 그냥 리턴합니다. 매번 새로 만들지 않는다는 거죠. 각종 Wrapper 클래스에 있는 많은 메쏘드 들이 이렇게 구현되어 있습니다.

Calendar.getInstance() 를 호출하면, 사용자 환경에 맞는 Calendar 객체가 리턴됩니다. 보통은 GregorianCalendar가 리턴된죠.

(이 메쏘드의 이름은 좀 잘못지어진 것 같습니다. 보통 getInstance()는 singleton 패턴에서 쓰이는 이름입니다.)


5. Factory Method의 종류


예제에서는 Factory의 인스턴스를 만들지 않고, static 메쏘드인 create()만을 호출했습니다. 이런 방식을 static factory method라고 합니다.

그냥 factory method라고 하면, factory의 인스턴스를 만들어서 쓰는 방식입니다. static factory에 비해 사용 빈도는 좀 떨어지지만, factory의 인스턴스에 귀속되는 객체를 생성해야 할 때는 이런 방식을 씁니다.(static factory에 비해 많이 쓰지 않으므로 자세한 것은 생략합니다.



Posted by hoonihoon