I have recently tried programming various versions of Iterator and Observer Patterns in Java, but currently I'm stuck at the implementation of both in one project:
What I'm trying to accomplish is to iterate through an ArrayList, which contains elements of type and after each iteration-process to inform the Observer about the change and the containing element. Also I want to be able to choose the "type" of iterator in my separate classes
Edit: I finally finished the project, hopefully this is the correct version of a "Observer Iterator", any tips on how to improve the code are greatly appreciated, but thanks to everybodys' encouraging tips.
Code:
First of all, the helper class for the Observer interface, which implements the update method. Changes with every iteration process and prints out the element.
package iteratorObserver;
import java.util.List;
public class ConcreteObserver implements Observer{
@Override
public void update(String element) {
System.out.println("The current element is: " + element);
}
}
The actual Observer interface:
package iteratorObserver;
public interface Observer<E> {
void update(String element);
}
Following that, the same by using a ConcreteSubject and an abstract class Subject The observer pattern requires the getState and setState, so I integrated both into the next method. Getting the element by iterator.next aswell as setting it.
package iteratorObserver;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ConcreteSubject<E> extends Subject implements IteratorStandardFilter<E>{
List<String> listElements = new ArrayList<String>();
private int index;
private Iterator<E> iterator;
public ConcreteSubject(Iterator<E> iterator, List<String> listElements){
index = 0;
this.iterator = iterator;
this.listElements = listElements;
}
public void addElement(String element) {
listElements.add(element);
notifyObservers(element);
}
// check the size of the elements list and return if there are still
// elements left out
@Override
public boolean hasNext() {
if ((listElements.size() == index))
return false;
return true;
}
// iterate to the next element, not sure if it's overridden, since the
// actual next method of the iterator is still in use
@Override
public E next() {
E result = iterator.next();
index++;
notifyObservers((String) result);
return result;
}
}
Subject class, only used for the standard observer methods
package iteratorObserver;
import java.util.ArrayList;
import java.util.List;
public class Subject {
public List<Observer> listObservers = new ArrayList<Observer>();
public void addObserver(Observer observer){
listObservers.add(observer);
}
public void removeObserver(Observer observer){
listObservers.remove(observer);
}
public <E> void notifyObservers(String element){
for(Observer observerHelp : listObservers){
observerHelp.update(element);
}
}
}
Since i want to add various filters, not only the standard list-iterator, i added a class IteratorStandardFilter, as you can see here:
package iteratorObserver;
import java.util.Iterator;
public interface IteratorStandardFilter<E> extends Iterator<E> {
public boolean hasNext();
public E next();
}
And finally, the Test method, the main:
package iteratorObserver;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class iteratorObserverMain {
public static void main(String [] args){
List<String> listElements = new ArrayList<String>();
listElements.add("hello");
listElements.add("there");
listElements.add("everybody");
listElements.add("it");
listElements.add("works");
listElements.add("Thanks for your help. Nice and encouraging forum");
Iterator<String> iterator = listElements.iterator();
ConcreteSubject<String> concreteSubject = new ConcreteSubject<String>(iterator, listElements);
concreteSubject.addObserver(new ConcreteObserver());
while(concreteSubject.hasNext()){
concreteSubject.next();
}
}
}