Nếu bạn không muốn cấu trúc lại mã và bạn có thể sử dụng Java 8, có thể sử dụng các tham chiếu Phương thức.
Một bản demo đơn giản đầu tiên (xin lỗi các lớp bên trong tĩnh)
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;
}
}
Đầu ra
241
4
null
2
Giao diện Getterchỉ là một giao diện chức năng, bạn có thể sử dụng bất kỳ tương đương.
GetterResultlớp, bộ truy cập loại bỏ cho rõ ràng, giữ kết quả của chuỗi getter, nếu có, hoặc chỉ mục của getter cuối cùng được gọi.
Phương pháp getterChainnày là một đoạn mã đơn giản, soạn sẵn, có thể được tạo tự động (hoặc thủ công khi cần).
Tôi cấu trúc mã để khối lặp lại là hiển nhiên.
Đây không phải là một giải pháp hoàn hảo vì bạn vẫn cần xác định một tình trạng quá tải getterChain cho mỗi số lượng getters.
Tôi sẽ cấu trúc lại mã thay vào đó, nhưng nếu không thể và bạn thấy mình sử dụng chuỗi getter dài thường thì bạn có thể xem xét việc xây dựng một lớp với các tình trạng quá tải mất từ 2 đến 10, getters.
nullkiểm tra nhiều như vậy, vìwsObject.getFoo().getBar().getBaz().getInt()đã là một mùi mã. Đọc "Luật của Demeter" là gì và thích cấu trúc lại mã của bạn cho phù hợp. Sau đó, vấn đề với cácnullkiểm tra cũng sẽ biến mất. Và suy nghĩ về việc sử dụngOptional.