Whiteship's Note


[NullPE] SpEL 때문에 고민 해결

Java : 2010.02.10 18:47


애초에 MVEL.eval() 내부에서 레퍼런스를 타고 갈 때 null 처리를 해줄 수 있는 방법을 찾았다면 Null Object 패턴까지 적용할 생각은 안 들었을테고, 그럼 Null Object 패턴을 어떻게 적용해야 깔끔한가?에 대한 고민도 안했을 텐데.. 그 실마리가 바로 MVEL 대신 SpEL을 사용하는 것이었습니다. 이론... OTL

SpEL은 스프링 3.0에 새로 추가된 기능인데 이 녀석이 할 수 있는 멋진 일들에 비해 아직 이것을 어떻게 활용해야 할지 제대로 파악이 되지 않은 상태입니다.(제가 파악이 안됐다는 것이지 일반적으로 그렇다는 것이 아니오니 오해 마시기 바랍니다.)


/**
 * Created by IntelliJ IDEA.
 * User: whiteship
 * Date: 2010. 2. 10
 * Time: 오후 6:38:11
 */
public class SpELNullTest {

    @Test
    public void SafeNavigation(){
        ExpressionParser parser = new SpelExpressionParser();

        SpringSprout ss = new SpringSprout();
        StandardEvaluationContext context = new StandardEvaluationContext(ss);

        String myName = parser.parseExpression("whiteship?.name").getValue(context, String.class);
        assertThat(myName, is(nullValue()));
    }

    class Whiteship{
        String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }

    class SpringSprout{
        Whiteship whiteship;

        public Whiteship getWhiteship() {
            return whiteship;
        }

        public void setWhiteship(Whiteship whiteship) {
            this.whiteship = whiteship;
        }
    }

}

흠냐.. 괜찮군요!

?. 가 아니라 그냥 . 로 연결하면 null 객체에 대고 getName()을 호출하는 격이라 에러가 납니다. ?, 연산식이 SpEL에서 지원하는 Safe Navigation이라는 녀석입니다.

이것 말고도 삼항 연산식도 제공하며 삼항 연산식에서 반복을 줄일 엘비스 연산식도 제공합니다. 아무튼 스프링은 참.. 멋지네요. +_+

덕분에 NullPE 고민 해결입니다.
top

TAG NullFE, SpEL

[NullPE] NullPointerException 때문에 고민 1

Java : 2010.02.10 11:46


레퍼런스를 사용하는 쪽에서 null 체크를 하면 되지만.. 그러지 못하는 경우가 있어서..

MVEL.eval(column.getPath(), entity, Integer.class)

column의 getPath()에는 item의 속성을 타고 타고 들어가는 경로도 들어옵니다. 그럴 때 타고 가는 중간에 null을 만나면 에러가 나죠. 제어할 수가 있다면 null 체크 하는 구문만 넣어서 버그를 수정하겠지만.. 지금은.. 좀.. @_@;;

그래서 Null Object Pattern이라는게 생각났고 이걸 적용해볼까 했습니다.

http://www.refactoring.com/catalog/introduceNullObject.html
http://en.wikipedia.org/wiki/Null_Object_pattern

Item 클래스의 레퍼런스 타입 변수를 반환하는 게터들이 다음과 같이 바꼈습니다.

    public Code getDelivery() {
        return NullObjectUtil.eval(delivery);
    }

    public Code getCar() {
        return NullObjectUtil.eval(car);
    }

    public Code getItemGroup() {
        return NullObjectUtil.eval(itemGroup);
    }

    public Supp getSupp() {
        return NullObjectUtil.eval(supp);
    }

public class NullObjectUtil {
   
    public static Code eval(Code code) {
        return code != null ? code : new NullCode();
    }

    public static Supp eval(Supp supp) {
        return supp != null ? supp : new NullSupp();
    }
}

그리고 domain.nullobject 패키지를 만들고

public class NullCode extends Code {
}

public class NullSupp extends Supp {
}

이렇게 NullObject 클래스들을 만들어 줬습니다.

이렇게 할지;;;

public Code getProcess(){
    return Code.basicIfNull(process);
}

이런식으로 할지. 고민입니다. 어떤게 왜 나은걸까나;; @_@


top