Реализация рекурсивной функции для составного шаблона? - PullRequest
0 голосов
/ 02 ноября 2019

Я реализовал составной шаблон с составным классом и листовым классом. Составной класс содержит ArrayList своих дочерних объектов (который может быть типа листа или составного). Каждый класс, как листовой, так и составной, имеет логическую переменную под названием «выполняется». Мой составной класс может быть классом 'and' или an 'или' - если это класс 'and', он требует, чтобы все его потомки были удовлетворены, чтобы он был удовлетворен. Если это класс 'или', для его удовлетворения требуется хотя бы один из его дочерних элементов.

У меня возникают проблемы при написании рекурсивной функции isSatisfied для составного класса, чтобы проверить, все лиего дети довольны, и поэтому было бы тоже. Это рекурсивно, потому что если у составного объекта есть дочерние объекты, которые являются составными, он должен также проверять все свои дочерние объекты и т. Д. Вот что я пробовал (это неверно). Любая помощь будет оценена.

public boolean isSatisfied(Component g) {
        if (type.equals('and')) {
            for (Component i : ((Composite) g).getChildren()) {
                if (i instanceof Composite) { //it's a composite
                    isSatisfied(i);
                } else { //it's a leaf
                    if (i.satisfied() == true) {
                        return true;
                    } else {
                        return false;
                    }
                }
            }
            return false;
        } else if (type.equals('or')) {
            for (Component i : ((Composite) g).getChildren()) {
                if (i instanceof Composite) {
                    isSatsified(i);
                } else {
                    if (i.satisfied() == true) {
                        return true;
                    } 
                }
            }
            return false;
        }


    }

1 Ответ

0 голосов
/ 03 ноября 2019

Если satistifed() является свойством компонента (корневой тип в шаблоне), то это свойство должно быть объявлено в интерфейсе:

public interface Component {
    boolean isSatisfied();
}

Тогда рекурсияпроисходит как следствие вызова метода на дочерних компонентах:

public boolean isSatisfied() {
    if( type.equals("and")) {
        for( Component component : components ) {
            if( !component.isSatisfied() ) {
                return false;
            }
        }
        return true;
    }
}

(Если заданный component для одной из итераций цикла окажется составным, тот же метод будет вызван снова, следовательно,, рекурсия).

Пока мы на этом, дизайн также может быть улучшен за счет исключения использования строки в качестве логического маркера (часть, где type.equals("and")). Если данный составной объект не будет меняться между типом AND и типом OR во время выполнения, рассмотрите возможность использования отдельных классов AndComposite и OrComposite. Если по какой-то причине вы хотите, чтобы ваш композит изменял свое поведение во время выполнения, я бы использовал boolean или перечислимый тип, чтобы различать их.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...