Убедитесь, что метод вызывается для всех объявленных и унаследованных членов некоторого типа - PullRequest
2 голосов
/ 16 февраля 2012

Я хочу извиниться за заголовок, но я не знал, как суммировать эту проблему.


У меня есть следующий класс с именем AbstractWriter:

public class AbstractWriter {

    private boolean changePerformed = false;

    // Some Setters

    private void changePerformed() {
        if (!changePerformed)
            changePerformed = true;
    }

    public boolean isChangePerformed() {
        return changePerformed;
    }

    protected <S> void setValue(
        Class<S> type, Object oldValue, Object newValue, Setter setter) {
        // Do something
        changePerformed();
    }
}

Каждый раз, когда вызывается установщик, вызывается метод setValue(…). Все сеттеры реализуют это правило.

Тогда есть AgeWriter, расширенный от AbstractWriter:

public class AgeWriter extends AbstractWriter {
    // Some Setters
}

И, опять же, есть HumanWriter:

public class HumanWriter {

    // Some setter calls are delegated to this Writer
    private AgeWriter ageWriter = new AgeWriter();

    // Some Setters

}

Когда я сейчас вызываю метод isChangePerformed() на HumanWriter, я знаю только, был ли вызван установщик на HumanWriter, но нет, если один из этих установщиков делегатов AgeWriter.

Я сейчас ищу общий способ решения этой проблемы. Вот несколько способов, которые я попробовал, соответственно подумал:

  • Попробуйте найти всех членов типа AbstractWriter с помощью Reflection. Но getDeclardFields пропускает унаследованные и getFields у private.
  • Сделайте isChangePerformed() abstract, чтобы каждая реализация должна убедиться, что она реализована правильно.
  • Создайте abstract метод getAbstractWriters, который возвращает все AbstractWriter s, используемые внутри этого типа.

Что бы вы подумали, чтобы решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 16 февраля 2012

Моя идея может быть глупой.Но я думаю, что это должно работать :).Вы можете использовать список авторов ...

public abstract class AbstractWriter {

    private List<AbstractWriter> writers;

    //...

    private boolean changePerformed = false;

    //...


    public boolean isChangePerformed() {
        for (AbstractWriter writer : writers) {
            if(writer.isChangePerformed() && changePerformed) {
                return true;
            }
        }
        return false;
    }
}
0 голосов
/ 16 февраля 2012

Если вы оставите ageWriter закрытым для HumanWriter, ни один внешний объект не сможет напрямую вызвать установщик на AgeWriter.Используйте инкапсуляцию, не предоставляя никакого доступа к ageWriter, и используйте методы на HumanWriter, которые делегируют ageWriter.

Вы также можете использовать шаблон наблюдаемого / наблюдателя (слушатели изменения свойств JavaBeans) и добавить HumanWriter в качестве слушателя AgeWriter.Таким образом, каждое изменение свойства ageWriter будет вызывать событие, которое будет отправлено HumanWriter.

...