यदि आप कोड को रिफलेक्टर नहीं करना चाहते हैं और आप जावा 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;
}
}
उत्पादन
२४१
४
अशक्त
२
इंटरफ़ेस Getter
सिर्फ एक कार्यात्मक इंटरफ़ेस है, आप किसी भी समकक्ष का उपयोग कर सकते हैं।
GetterResult
वर्ग, अभिगमकर्ताओं ने स्पष्टता के लिए छीन लिया, गेटर श्रृंखला के परिणाम को पकड़ें, यदि कोई हो, या अंतिम गेटर के सूचकांक को बुलाया जाए।
विधि getterChain
कोड का एक सरल, बॉयलरप्लेट टुकड़ा है, जो स्वचालित रूप से (या मैन्युअल रूप से आवश्यक होने पर) उत्पन्न किया जा सकता है।
मैंने कोड को संरचित किया है ताकि दोहराए जाने वाला ब्लॉक स्वयं स्पष्ट हो।
यह एक सही समाधान नहीं है क्योंकि आपको अभी भी getterChain
प्रति गेटर्स की संख्या के एक अधिभार को परिभाषित करने की आवश्यकता है ।
मैं इसके बजाय कोड को रिफलेक्टर करूंगा, लेकिन अगर आप लंबे गेट्टर चेन का उपयोग करके अपने आप को नहीं पा सकते हैं, तो आप अक्सर ओवरलोड के साथ एक क्लास बनाने पर विचार कर सकते हैं, जो कि 2, 10, गेटर्स से लेते हैं।
null
लगता है किwsObject.getFoo().getBar().getBaz().getInt()
पहले से ही एक कोड गंध के बाद से, बहुत बुरा नहीं होगा । पढ़ें कि "लॉ ऑफ़ डेमेटर" क्या है और तदनुसार अपने कोड को फिर से भरना पसंद करें। फिरnull
चेक के साथ समस्या भी दूर हो जाएगी। और उपयोग करने के बारे में सोचेंOptional
।