[디자인 패턴(Design Pattern)] 팩토리 메소드(Factory Method)

업데이트:

카테고리:

태그:


팩토리 메소드 패턴이란?

팩토리 패턴이라고도 부르는 팩토리 메소드 패턴은 생성 패턴 중의 하나로 상위 클래스에서는 인터페이스만을 정의하고 객체 생성을 서브 클래스에서 처리하도록 분리하여 입력 값에 따라 해당되는 서브 클래스의 인스턴스를 리턴해주는 패턴이다. 팩토리 패턴은 생성해야 하는 객체의 클래스를 예측할 수 없을 경우 유용하게 사용된다.

장점

  • 객체의 생성부를 캡슐화하여 클라이언트 코드와 결합도(의존도)를 낮춘다.

객체지향의 성질인 다형성을 이용해 인터페이스를 정의한 걕체는 모두 인터페이스로 접근이 가능하므로 코드가 유연해진다. 그리고 객체의 생성부를 분리하였으므로 새로운 서브클래스가 추가 및 삭제 되더라도 생성부만 수정하면 된다.

예시 (Kotlin)

나이와 이름 그리고 타입을 입력 받아 Man 객체 또는 Woman 객체를 생성하는 HumanFactory를 만들어 보자

우선은 Man 클래스와 Woman 클래스의 상위 클래스가 될 Human 클래스를 만든다. 서브 클래스의 인터페이스만 구현할 것이므로 추상 클래스로 만들었다.

abstract class Human{
    abstract var age : Int
    abstract var name : String
    override fun toString(): String {
        return "name : $name , age : $age"
    }
}

다음은 Human 클래스의 서브 클래스인 Man 클래스와 Woman 클래스이다.

data class Man(
    override var age : Int,
    override var name : String
) : Human(){
    override fun toString(): String {
        return "Man - ${super.toString()}"
    }
}
data class Woman(
    override var age : Int,
    override var name : String
) : Human(){
    override fun toString(): String {
        return "Woman - ${super.toString()}"
    }
}

각 서브 클래스는 toString()을 오버라이딩 하여 해당 객체가 Man 객체인지 Woman 객체인지 알 수 있도록 하였다.

다음은 객체를 생성해줄 HumanFactory이다.

class HumanFactory{
    companion object{
        fun getHuman(type : String, age: Int, name: String) : Human =
            if (type == "man") Man(age, name)
            else Woman(age, name)
    }
}

if - else문을 이용해 type이 man일 경우 Man객체를, 아닐 경우 Woman객체를 생성하도록 하였다.

다음 코드를 통해 HumanFactory가 객체를 잘 생성하는지 확인한다.

fun main(args: Array<String>) {
    val man = HumanFactory.getHuman("man",20,"김철수")
    val woman = HumanFactory.getHuman("woman",22,"김영희")
    println(man.toString())
    println(woman.toString())
}


출력 :

Man - name : 김철수 , age : 20
Woman - name : 김영희 , age : 22