Kodu yeniden düzenlemek istemiyorsanız ve Java 8'i kullanabiliyorsanız, Yöntem referanslarını kullanmak mümkündür.
Önce basit bir demo (statik iç sınıfları mazur görün)
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;
}
}
Çıktı
241
4
boş
2
Arayüz Getter
sadece işlevsel bir arayüzdür, herhangi bir eşdeğerini kullanabilirsiniz.
GetterResult
sınıf, erişimciler netlik için çıkarılır, varsa alıcı zincirinin sonucunu veya çağrılan son alıcının dizinini tutar.
Yöntem getterChain
, otomatik olarak (veya gerektiğinde manuel olarak) oluşturulabilen basit, standart bir kod parçasıdır.
Kodu, tekrar eden bloğun kendini belli etmesi için yapılandırdım.
Bu mükemmel bir çözüm değil, çünkü hala bir aşırı yük tanımlamanız gerekiyor getterChain
Her alıcı için .
Bunun yerine kodu yeniden düzenlerdim, ancak yapamazsanız ve kendinizi uzun alıcı zincirleri kullanarak bulursanız, genellikle 2 ila 10 alıcı arasında değişen aşırı yüklere sahip bir sınıf oluşturmayı düşünebilirsiniz.
null
çekleri bu kadar önemsememwsObject.getFoo().getBar().getBaz().getInt()
. "Demeter Yasası" nın ne olduğunu okuyun ve kodunuzu buna göre yeniden düzenlemeyi tercih edin. O zamannull
çeklerdeki sorun da ortadan kalkacak. Ve kullanmayı düşününOptional
.