Java - ручная проверка объекта по белому списку - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь написать класс для получения мегаобъекта и убедиться, что только определенные поля были изменены, обычно вы бы аннотировали / добавляли проверку таким способом, но, к сожалению, это не вариант в этом случае, я могу изменить один класс, над которым я работаю, который получит очень большой (и очень вложенный!) объект, который я должен как-то проверить.

Сначала я хотел составить «список». вещей, которые можно изменить, затем переберите все свойства объекта и проверьте, обновлено ли что-либо, чего нет в «белом списке», у меня есть старая версия объекта, поэтому я могу проверить каждое поле на соответствие старому один, чтобы подтвердить, но я не совсем уверен, как это сделать, или если есть лучшее решение. Я никогда не пробовал что-то подобное раньше.

Любые предложения приветствуются. Если нет более эффективных решений, как мне создать белый список / выполнить итерацию по всем свойствам / вложенным свойствам мегаобъекта?

ОБНОВЛЕНИЕ: Основываясь на предложениях, вот что я пытаюсь, у него все еще есть несколько проблем (пожалуйста, обратите внимание, что я просто разбрасываю вещи, это ни в коем случае не мой последний класс или хорошее программирование):

  1. isTraversable works в коллекциях, но я не уверен, как проверить пользовательские классы, например. класс Person, который по-прежнему нужно было бы повторять.
  2. Повсюду есть циклические c ссылки, не знаю, как с ними обращаться.
public class Test {
       private Object obj1;
       private Object obj2;
       private List<String> whitelist;

        public void validate(Object objectToTraverse, 
                             Object objectToCompareTo, 
                             List<String> whitelist){
            this.obj1 = objectToTraverse;
            this.obj2 = objectToCompareTo;
            this.whitelist = whitelist;

            traverseAndCompare(obj1, obj2);
        }

        private void traverseAndCompare(Object objectToTraverse, 
                                        Object objectToCompareTo){
            try {
                for (Field field : objectToTraverse.getClass()
                        .getDeclaredFields()) {

                    field.setAccessible(true);
                    Object fieldValue = field.get(objectToTraverse);

                    if (isTraversable(field)) {
                        traverseAndCompare(field.get(objectToTraverse), 
                                field.get(objectToCompareTo));
                    } else {
                        getFieldValuesAndCompare(field, obj1, obj2);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        private boolean getFieldValuesAndCompare(Field field, 
                                                 Object obj1, 
                                                 Object obj2) 
                throws Exception{

            Object value1 = field.get(obj1);
            Object value2 = field.get(obj2);

            return compare(value1, value2);
        }

        private boolean compare(Object value1, 
                                Object value2){
            return Objects.equals(value1, value2);
        }

        private boolean isTraversable(Field field){
            // This should handle collections, but it does not work 
            // on custom classes, eg. Person class
            if (Collection.class.isAssignableFrom(field.getType())) {
                return true;
            }

            // Need to somehow figure out is this is a class with 
            // properties I can traverse, or something with a value, 
            // like String, Long, etc, hopefully
            // without listing everything

            return false;
        }
    }

1 Ответ

0 голосов
/ 29 февраля 2020

Ввод описательного ответа, поскольку объект не может быть передан по юридической причине.

У вас есть несколько вариантов. Каждый с за и против.

Отражение

Вы можете вести список полей, которые нельзя изменять, используя их полный путь. Как AB c. Затем вы можете написать чистый код отражения или использовать обычные утилиты, такие как http://commons.apache.org/proper/commons-beanutils/, чтобы получить значения (даже глубоко в дереве объектов) и сравнить.

Требуется меньше кода и меньше обслуживания. Но вам нужно знать точный список полей черного списка. По производительности это займет немного больше времени.

Техника простого простого кода

Напишите свой собственный компаратор или метод в java - go через все поля, которые не могу изменить и решить. Нужно много кода, но он очень прост в обслуживании и оптимален с точки зрения производительности.

...