Đó có phải là một cách thực hành tốt để sử dụng sự phản chiếu nếu làm giảm đáng kể số lượng mã soạn sẵn?
Về cơ bản, có một sự đánh đổi giữa hiệu suất và có thể dễ đọc ở một bên và sự trừu tượng hóa / tự động hóa / giảm mã nồi hơi ở phía bên kia.
Chỉnh sửa: Đây là một ví dụ về việc sử dụng phản xạ được đề nghị .
Để đưa ra một ví dụ, giả sử có một lớp trừu tượng Base
có 10 trường và có 3 lớp con SubclassA
, SubclassB
và SubclassC
mỗi lớp có 10 trường khác nhau; chúng đều là những hạt đậu đơn giản Vấn đề là bạn có được hai Base
loại tham chiếu và bạn muốn xem các đối tượng tương ứng của chúng có cùng loại (phụ) không và có bằng nhau không.
Vì các giải pháp có giải pháp thô trong đó trước tiên bạn kiểm tra xem các loại có bằng nhau không và sau đó kiểm tra tất cả các trường hoặc bạn có thể sử dụng phản xạ và tự động xem liệu chúng có cùng loại không và lặp lại trên tất cả các phương thức bắt đầu bằng "get" (quy ước qua cấu hình), gọi chúng trên cả hai đối tượng và gọi bằng với kết quả.
boolean compare(Base base1, Base, base2) {
if (base1 instanceof SubclassA && base2 instanceof SubclassA) {
SubclassA subclassA1 = (SubclassA) base1;
SubclassA subclassA2 = (SubclassA) base2;
compare(subclassA1, subclassA2);
} else if (base1 instanceof SubclassB && base2 instanceof SubclassB) {
//the same
}
//boilerplate
}
boolean compare(SubclassA subA1, SubclassA subA2) {
if (!subA1.getField1().equals(subA2.getField1)) {
return false;
}
if (!subA1.getField2().equals(subA2.getField2)) {
return false;
}
//boilerplate
}
boolean compare(SubclassB subB1, SubclassB subB2) {
//boilerplate
}
//boilerplate
//alternative with reflection
boolean compare(Base base1, Base base2) {
if (!base1.getClass().isAssignableFrom(base2.getClass())) {
System.out.println("not same");
System.exit(1);
}
Method[] methods = base1.getClass().getMethods();
boolean isOk = true;
for (Method method : methods) {
final String methodName = method.getName();
if (methodName.startsWith("get")) {
Object object1 = method.invoke(base1);
Object object2 = method.invoke(base2);
if(object1 == null || object2 == null) {
continue;
}
if (!object1.equals(object2)) {
System.out.println("not equals because " + object1 + " not equal with " + object2);
isOk = false;
}
}
}
if (isOk) {
System.out.println("is OK");
}
}