JAVA enum으로 팩토리 만들기.

곽민종·2022년 5월 29일
0

2가지 방식을 정리해본다.

  1. enum이 클래스의 생성자를 갖고 있는 방식.
package com.example.demo.enumTest.type;

import com.example.demo.enumTest.connector.*;
import java.util.function.Supplier;

public enum ConnectionType {

    FTP(FTPConnector::new),
    HTTP(HttpConnector::new),
    SUPERMAN(SuperManConnector::new),
    NEW(NewConnector::new);

    ConnectionType(Supplier<BaseConnector> instantiator){
        this.instantiator= instantiator;
    }

    Supplier<BaseConnector> instantiator;

    public BaseConnector newInstance(){
        return this.instantiator.get();
    }
}

enum으로 현재 프로젝트가 지원하는 Connecting 방식을 정의하고,
각 방식별로 BaseConnector의 생성자를 갖게하여
newInstance()를 호출해 사용하는 방식이다.

//Info info 는 connectionType을 멤버변수로 갖고 있는 객체.
BaseConnector connector = info.getConnectionType().newInstance();

사용하는 곳에서는 그저 connectionType.newInstance()를 호출하여 새로운 커넥터를 생성하면 된다.

위 방식은 Class가 no argument constructor를 갖고 있어야 오류가 나지 않는다.

만일 인자를 필요로 하는 constructor만 갖고있다면

Supplier<T>
Function<T,Q>
BiFunction<T,Q,R>

중에 알맞는 걸 사용하도록 하자.

만일 그 이상이거나 생성자의 인자로 generic 을 받는다면,
아래와 같이 enum을 구성해도 된다.

  1. Class를 갖고있는 방식
package com.example.demo.enumTest.type;

import com.example.demo.enumTest.file_formatter.BaseFormatter;
import com.example.demo.enumTest.file_formatter.SimpleKeyValue;
import com.example.demo.enumTest.file_formatter.XmlFormatter;
import org.w3c.dom.Document;

import java.lang.reflect.InvocationTargetException;

public enum FileType {

    SIMPLE_KEY_VALUE(SimpleKeyValue.class, String.class),
    XML(XmlFormatter.class, Document.class);

    FileType(Class<? extends BaseFormatter<?>> formatClass,Class<?> rawDataClass){
        this.formatClass = formatClass;
        this.rawDataClass = rawDataClass;

    }

    Class<? extends BaseFormatter<?>> formatClass;
    Class<?> rawDataClass;

    public BaseFormatter<?> newInstance(Object rawData, String rule){
        try {
            return this.formatClass.getConstructor(this.rawDataClass,String.class).newInstance(rawData,rule);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
}

이 방식은 reflection을 이용해 newInstance를 만든다.
생성할 클래스 (formatClass), generic 인자 클래스(rawDataClass) 를 인자로 갖는 형태이다.

사용할때는 위와 똑같이 사용하면 된다.

//info 는 FileType을 멤버변수로 갖고있는 객체
//rawData와 rule은 적당한 객체.
BaseFormatter<?> formatter = info.getFileType().newInstance(rawData,rule);
profile
julysky입니다.

0개의 댓글