코드를 리팩토링하고 싶지 않고 Java 8을 사용할 수있는 경우 메서드 참조를 사용할 수 있습니다.
먼저 간단한 데모 (정적 내부 클래스를 용서하십시오)
public class JavaApplication14
{
static class Baz
{
private final int _int;
public Baz(int value){ _int = value; }
public int getInt(){ return _int; }
}
static class Bar
{
private final Baz _baz;
public Bar(Baz baz){ _baz = baz; }
public Baz getBar(){ return _baz; }
}
static class Foo
{
private final Bar _bar;
public Foo(Bar bar){ _bar = bar; }
public Bar getBar(){ return _bar; }
}
static class WSObject
{
private final Foo _foo;
public WSObject(Foo foo){ _foo = foo; }
public Foo getFoo(){ return _foo; }
}
interface Getter<T, R>
{
R get(T value);
}
static class GetterResult<R>
{
public R result;
public int lastIndex;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args)
{
WSObject wsObject = new WSObject(new Foo(new Bar(new Baz(241))));
WSObject wsObjectNull = new WSObject(new Foo(null));
GetterResult<Integer> intResult
= getterChain(wsObject, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);
GetterResult<Integer> intResult2
= getterChain(wsObjectNull, WSObject::getFoo, Foo::getBar, Bar::getBar, Baz::getInt);
System.out.println(intResult.result);
System.out.println(intResult.lastIndex);
System.out.println();
System.out.println(intResult2.result);
System.out.println(intResult2.lastIndex);
// TODO code application logic here
}
public static <R, V1, V2, V3, V4> GetterResult<R>
getterChain(V1 value, Getter<V1, V2> g1, Getter<V2, V3> g2, Getter<V3, V4> g3, Getter<V4, R> g4)
{
GetterResult result = new GetterResult<>();
Object tmp = value;
if (tmp == null)
return result;
tmp = g1.get((V1)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g2.get((V2)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g3.get((V3)tmp);
result.lastIndex++;
if (tmp == null)
return result;
tmp = g4.get((V4)tmp);
result.lastIndex++;
result.result = (R)tmp;
return result;
}
}
산출
241
4
널
2
인터페이스 Getter
는 기능적 인터페이스 일 뿐이며 동등한 인터페이스를 사용할 수 있습니다.
GetterResult
클래스, 접근자는 명확성을 위해 제거되고, getter 체인의 결과 (있는 경우) 또는 마지막으로 호출 된 getter의 인덱스를 보유합니다.
이 메서드 getterChain
는 자동으로 (또는 필요할 때 수동으로) 생성 할 수있는 간단한 표준 코드 조각입니다.
반복되는 블록이 자명하도록 코드를 구성했습니다.
여전히 하나의 과부하를 정의해야하기 때문에 이것은 완벽한 솔루션이 아닙니다. getterChain
게터 수당 .
대신 코드를 리팩토링 할 수 있지만, 그렇게 할 수없고 긴 게터 체인을 자주 사용하는 경우 게터가 2 개에서 10 개까지 걸리는 오버로드가있는 클래스를 만드는 것을 고려할 수 있습니다.
null
이기 때문에 수표에 그렇게 신경 쓰지 않을 것wsObject.getFoo().getBar().getBaz().getInt()
입니다. "데메테르의 법칙" 이 무엇인지 읽고 그에 따라 코드를 리팩토링하는 것을 선호합니다. 그러면null
수표 문제 도 사라질 것입니다. 그리고Optional
.