I am trying to implement a custom iterator for a composite class and use different strategies in the iterator implementation depending on how the client wants to traverse the composite structure.
public class MyComposite implements Iterable<MyComponent> {
ArrayList<MyComponent> childComponents;
//MyComposite methods
@Override
public Iterator<MyComponent> iterator() {
return new MyIterator(this);
}
}
I would like to pass a MyIteratorStrategy
object as part of the iterator construction, however the Iterable
interface does not permit passing objects to the iterator
method.
public class SomeClient {
private void traverseComposite() {
MyComposite myComposite = new MyComposite();
MyIteratorStrategy fooStrategy = new MyIteratorStrategy("foo");
MyIteratorStrategy barStrategy = new MyIteratorStrategy("bar");
MyIterator fooIterator = myComposite.iterator(fooStrategy);
MyIterator barIterator = myComposite.iterator(barStrategy);
}
}
Here's how I'm utilizing the strategy in the iterator implementation:
public class MyIterator implements Iterator<MyComponent> {
MyComponent component;
MyIteratorStrategy strategy;
public MyIterator(MyComponent component, MyIteratorStrategy strategy) {
this.component = component;
this.strategy = strategy;
}
@Override
public Component next() {
if(strategy.isDone(component) {
//return some child component
} else {
//return some other child component
}
}
//rest of implementation
}
I'm trying to learn how to utilize design patterns, so perhaps I'm being overly general. How can I cleanly inject the strategy into the iterator?
Change MyIterator
to be the class that implements Iterable<MyComponent>
, instead of Iterator
. (You might want to rename it something like MyComponentScanner
for clarity.)
Move the public Iterator<MyComponent> iterator()
method over from the MyComposite
class to MyIterator
(or whatever you rename it).
Example...
public class MyComponentScanner implements Iterable<MyComponent> {
MyComponent component;
MyIteratorStrategy strategy;
public MyComponentScanner(MyComponent component, MyIteratorStrategy strategy) {
this.component = component;
this.strategy = strategy;
}
@Override
public Iterator<MyComponent> iterator() {
return new Iterator() {
@Override
public Component next() {
if(strategy.isDone(component) {
//return some child component
} else {
//return some other child component
}
}
};
}
//rest of implementation
}
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.