반응형

개인적으로 규칙 3과 규칙 4의 순서가 바뀌는 것이 좋다고 생각함.

 

클래스가 private 생성자만을 가지고 있다면 자신만이 객체를 생성할 수 있기 때문에 규칙 3. 싱글턴 패턴에서 private 생성자를 사용하였다. 또한 싱글턴은 메모리에 올려야 하는 정보(필드)가 있기 때문에 객체를 만들어서 사용한다.

 

싱글턴과는 다르게 메모리에 올려서 사용할 정보들은 없는 Util 클래스들은 객체를 만들 목적의 클래스가 아니다. 따라서 Util 클래스를 작성할 때는 private 생성자를 사용하여 객체 생성을 막는 것이 좋다.

 

아래는 private 생성자를 사용한 Netty의 io.netty.util.internal.StringUtil 소스코드이다.

public final class StringUtil {

    public static final String EMPTY_STRING = "";
    public static final String NEWLINE = SystemPropertyUtil.get("line.separator", "\n");

    public static final char DOUBLE_QUOTE = '\"';
    public static final char COMMA = ',';
    public static final char LINE_FEED = '\n';
    public static final char CARRIAGE_RETURN = '\r';
    public static final char TAB = '\t';
    public static final char SPACE = 0x20;

    private static final String[] BYTE2HEX_PAD = new String[256];
    private static final String[] BYTE2HEX_NOPAD = new String[256];
    private static final byte[] HEX2B;

    ...
    
    // private 생성자를 사용하여 객체 생성을 막는다. 
    private StringUtil() {
        // Unused.
    }

 

private 생성자가 아닌 클래스를 abstract로 선언하여 객체를 생성하지 못하도록 막을 수도 있다. 하지만 해당 클래스는 상속받은 하위 클래스를 만들게 된다면 객체가 결국에 생성되는 것이니 올바른 방법이 아니다.

 

아래는 abstract 클래스로 선언하여 사용한 Spring의 org.springframework.util.StringUtils 소스코드이다.

// abstract로 선언하여 직접적으로 객체는 만들 수 없지만, 상속 받은 하위클래스는 객체 생성이 가능하다.
public abstract class StringUtils {

	private static final String[] EMPTY_STRING_ARRAY = {};

	private static final String FOLDER_SEPARATOR = "/";

	private static final String WINDOWS_FOLDER_SEPARATOR = "\\";

	private static final String TOP_PATH = "..";

	private static final String CURRENT_PATH = ".";

	private static final char EXTENSION_SEPARATOR = '.';
    
    ...

 

/**
 * Spring의 StringUtils는 클래스는 객체 생성을 막기 위해 abstract를 클래스로 만들었지만
 * 하위 클래스가 상속받는다면 객체 생성이 가능
 *
 * @author gwon
 * @history
 *          2021. 10. 24. initial creation
 */
public class ChildSpringStringUtils extends StringUtils {

	public static void main(String[] args) {
		StringUtils stringUtils = new ChildSpringStringUtils();

		stringUtils.isEmpty("abc");
	}
}

 

 

반응형

+ Recent posts