CS/디자인패턴

[디자인패턴] FactoryMethod 패턴 (팩토리메소드)

mabb 2023. 5. 27. 19:03
반응형

▶디자인 패턴 ( Design Pattern)
:프로그램 개발 시 문제 해결을 위하여 빈번히 사용되는 개발자들의 경험, 내적인 축적에 대하여,
GoF(Gang of Four) 라 불리는 4인의 개발자들이 각각을 패턴으로 정의하고 이름을 붙였다.
이를 디자인 패턴 (Design Pattern) 이라고 한다.
 23개의 디자인 패턴을
『Elements of Reusable Object-Oriented Software』
라는 책으로 발간하였다.

Gang of Four 분들은 모두 안경을 썼다.

 
▷디자인 패턴의 용어를 빌리면 서로의 아이디어를 보다 용이하게 비교, 논의할 수 있게 된다.
▷재사용과 기능확장이 쉬운 소프트웨어를 만들기 위한 유익한 기법이 바로 디자인 패턴이다.
 
---------------------------------------------------------
1. Iterator
2. Adapter
3. Template Method
4. Factory Method
5. Singleton
6. Prototype
7. Builder
8. Abstract Factory
9. Bridge
10. Strategy
11. Composite
12. Decorator
13. Visitor
14. Chain of Responsibility
15. Facade
16. Mediator
17. Observer
18. Memento
19. State
20. Flyweight
21. Proxy
22. Command
23. Interpreter
---------------------------------------------------------

▶FactoryMethod 패턴

"상위클래스에서 객체(인스턴스) 생성에 대한 뼈대를 잡고

하위클래스에서 객체 생성에 대한 내용을 구체화"

"템플릿 메소드 패턴으로 인스턴스를 생성 하는 패턴"


-왜 사용하는가
-클래스다이어그램
-각 클래스(인터페이스)의 역할
-Java소스


▶FactoryMethod 패턴에 대한 이해

-인스턴스를 생성하는 패턴

-인스턴스를 생성해주는 객체를 Factory라고 표현한다.

-팩토리는 인스턴스를 만든다. 팩토리가 만들어준 인스턴스를 활용하여 특정 기능을 수행할 수 있다.

-동일한 절차로 생성하는 여러 종류의 인스턴스를 만들어서 사용하고자 할 때 팩퇴메소드패턴을 사용한다.

-팩토리를 상속(extends)받은 구상팩토리들 각각은 인스턴스를 상속(extends)받은 다양한 타입의 인스턴스를 만들어낸다. 

-템플릿메소드 패턴으로 인스턴스를 생성하는 패턴이 팩토리메소드패턴이다.

-인스턴스 생성을 템플릿메소드 패턴으로 수행하는 방법이다.

-인스턴스 생성 방법과 인스턴스를 생성할 클래스를 분리하는 것이다.

-상위클래스에서 인스턴스 생성방법( 인스턴스 생성을 위한 공통된 로직, 흐름, 뼈대 )을 템플릿메소드패턴으로 정의한다.

-하위클래스에서 특정 인스턴스를 생성하기 위한 구체적인 방법을 작성한다.
ex)
-여러 종류의 운송 수단에 대한  제조 방법은 같은 절차,로직,흐름을 가진다. 만들어낸 운송수단은 '운송'이라는 기능을 수행한다.

-운수업체는 "운송수단 제조공장에서 만든 운송수단을 이용하여 운송한다." 는 로직으로 운영된다.
-제조공장을 화물차제조공장, 화물선제조공장, 화물용기차제조공장으로 바꿔주면 각각의 공장은 알아서 화물차, 화물선, 화물기차를 만들어낸다. 운수업체는 기존의 로직 그대로 다양한 운송수단을 이용하여 '운송' 할 수 있다.

 

▶왜 사용하는가


같은 절차로 만들고 같은 방식으로 사용하는 여러 종류의 인스턴스를 만들기 위하여 각각의 클래스를 만들고 이를 클라이언트가 사용한다면 유지보수 및 재사용이 어려울 것이다.
특정한 로직,절차,흐름,뼈대로 생성되어 어떠한 기능을 수행하는 여러 종류의 인스턴스가 필요할 수 있다. 인스턴스 생성 절차만 정의하고 각각의 인스턴스를 생성하는 구상팩토리를 만들어 원하는 인스턴스를 생성하기 위해 사용한다.
 

▶클래스다이어그램

FactoryMethod패턴의 클래스다이어그램

 

▶각 클래스(인터페이스)의 역할

▷Client
:팩토리 인스턴스에 팩토리 하위 타입 인스턴스를 대입하여 사용한다.
▷Factory
:템플릿메소드패턴으로 인스턴스생성에 대한 절차를 정의한다.
▷Instance
:팩토리가 생성하는 인스턴스이다. 클라이언트가 사용할 동작을 추상메소드로 정의한다.
▷ConcreteFactory1과 ConcreteFactory2
:Factory의 추상메소드를 오버라이드하여 각각 인스턴스1과 인스턴스2를 만들어낸다.
▷ConcreteInstance1과 ConcreteInstance2
:구상팩토리들이 만들어내는 인스턴스들로, Instance를 extends하여 공통 동작을 오버라이드한다.
 

▶Java 소스

*java1.8 이전 버전을 사용하는 교재를 참고 하였습니다.
Java API 문서 등을 참조하여 제네릭을 적용하는 등 소스를 개선할 필요가 있습니다.
(https://docs.oracle.com/en/java/javase/20/docs/api/)

 

Client.java

package main.java.designpattern.factorymethod;

import main.java.designpattern.factorymethod.abstractfactory.Factory;
import main.java.designpattern.factorymethod.abstractfactory.Instance;
import main.java.designpattern.factorymethod.concretefactory.ConcreteFactory1;
import main.java.designpattern.factorymethod.concretefactory.ConcreteFactory2;

public class Client {

    public static void main(String[] args){

        Factory factory1 = new ConcreteFactory1();
        Factory factory2 = new ConcreteFactory2();

        Instance instance1 = factory1.create();
        Instance instance2 = factory2.create();

        instance1.instanceRun();
        instance2.instanceRun();

    }
}

 

Factory.java

package main.java.designpattern.factorymethod.abstractfactory;

public abstract class Factory {


    //create() 메소드는 템플릿메소드패턴으로 인스턴스를 생성하는 (템플릿)팩토리메소드이다.
    //팩토리는 인스턴스를 생성한다.

    public final Instance create(){

        Instance instance;
        String dataForCreateInstance = getDataForCreateInstance();
        instance = createInstance(dataForCreateInstance);

        return instance;
    }

    protected abstract String getDataForCreateInstance();
    protected abstract Instance createInstance(String dataForCreateInstance);

}

 

Instance.java

package main.java.designpattern.factorymethod.abstractfactory;

public abstract class Instance {

    public abstract void instanceRun();

}

 

ConcreteFactory1.java

package main.java.designpattern.factorymethod.concretefactory;

import main.java.designpattern.factorymethod.abstractfactory.Factory;
import main.java.designpattern.factorymethod.abstractfactory.Instance;

public class ConcreteFactory1 extends Factory {

    @Override
    protected String getDataForCreateInstance() {
        return "<<인스턴스1 생성을 위한 데이터>>";
    }

    @Override
    protected Instance createInstance(String dataForCreateInstance) {
        return new ConcreteInstance1( getDataForCreateInstance() );
    }

}

 

ConcreteFactory2.java

package main.java.designpattern.factorymethod.concretefactory;

import main.java.designpattern.factorymethod.abstractfactory.Factory;
import main.java.designpattern.factorymethod.abstractfactory.Instance;

public class ConcreteFactory2 extends Factory {

    @Override
    protected String getDataForCreateInstance() {
        return "[[인스턴스2 생성을 위한 데이터]]";
    }

    @Override
    protected Instance createInstance(String dataForCreateInstance) {
        return new ConcreteInstance2( getDataForCreateInstance() );
    }
}

 

ConcreteInstance1.java

package main.java.designpattern.factorymethod.concretefactory;

import main.java.designpattern.factorymethod.abstractfactory.Instance;

public class ConcreteInstance1 extends Instance {

    private String needData;

    ConcreteInstance1(String needData){
        this.needData = needData;
        System.out.println(needData + "를 가진 인스턴스1객체가 생성됩니다.");
    }

    @Override
    public void instanceRun(){
        System.out.println("####인스턴스1이 <" + needData + "> 로 동작하고 있습니다.####");
    }

}

 

ConcreteInstance2.java

package main.java.designpattern.factorymethod.concretefactory;

import main.java.designpattern.factorymethod.abstractfactory.Instance;

public class ConcreteInstance2 extends Instance {

    private String needData;

    ConcreteInstance2(String needData){
        this.needData = needData;
        System.out.println(needData + "를 가진 인스턴스2객체가 생성됩니다.");
    }

    @Override
    public void instanceRun() {
        System.out.println("!!!!인스턴스2가 " + needData + "로 동작합니다.!!!!");
    }
}

 
---------------------------------------------------------
※참고자료
-Java언어로 배우는 디자인 패턴 입문
-Headfirst Design Pattern
-나무위키, 위키백과, 네이버백과
-리팩토링구루(https://refactoring.guru/ko)

반응형