简体   繁体   中英

Implementing recursive function for composite pattern?

I have implemented a composite pattern with a composite class and a leaf class. The composite class contains an ArrayList of its children objects (which may be of type leaf or composite). Each class, both leaf and composite, have a boolean variable called 'satisfied'. My composite class can either be an 'and' or an 'or' class - if it's an 'and' class, it requires all of its children to be satisfied for it to be satisfied. If it's an 'or' class, it requires at least one of its children to be satisfied for it to be satisfied.

I am having trouble writing a recursive function 'isSatisfied' for the composite class to check whether all of its children are satisfied and therefore it would be too. It's recursive because if the composite object has children that are composite, it needs to check all of its children too etc. Here is what I've tried (it's incorrect). Any help would be appreciated.

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;
        }


    }

If satistifed() is a property of the component (the root type in the pattern), then this property should be declared in the interface:

public interface Component {
    boolean isSatisfied();
}

Then the recursion happens as a consequence of calling the method on the children components:

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

(If a given component for one of the loop iteration happens to be a composite, the same method will be called again, hence, recursion).

While we're at it, the design can also be improved by avoiding the use of a string as a boolean marker (the part where type.equals("and") ). If a given composite object is not going to change between AND-type and OR-type at runtime, consider having a separate AndComposite and OrComposite classes. If for some reason you want your composite to change their behavior at run-time, then I would use either a boolean or an enumerated type to distinguish them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM