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 Getter
chỉ là một giao diện chức năng, bạn có thể sử dụng bất kỳ tương đương.
GetterResult
lớ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 getterChain
nà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.
null
kiể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ácnull
kiểm tra cũng sẽ biến mất. Và suy nghĩ về việc sử dụngOptional
.