Search code examples
javadesign-patternsobserver-pattern

Java Observer Pattern finding sender?


observer.update();

Above method makes the visibility of observers "GONE", but i want to change all other observers except sender observer. How can i control this ?

My all actions are observer and register themself in their constructor like below,

public class ParentAction extends AbstractAction implements IActionObserver{
    private ArrayList<IAction> lSubItems;
    private View subView;

    public ParentAction( String ItemText,int drawable,ArrayList<IAction> SubItems) {
        super(ItemText,drawable);       
        lSubItems = SubItems;   
        ActionHolder.getInstance().registerObserver(this);
    }

    @Override
    public void update() {
        getSubView().setVisibility(View.GONE);
    }  ...

ActionHolder

public class ActionHolder implements IActionSubject {
    private static ActionHolder uniqueActionHolder;
    private ArrayList observers;

    private ActionHolder() {
        observers = new ArrayList();
    }

    public static synchronized ActionHolder getInstance() {
        if (uniqueActionHolder == null) {
            uniqueActionHolder = new ActionHolder();
        }
        return uniqueActionHolder;
    }

    public void registerObserver(IActionObserver o) {
        observers.add(o);
    }

    public void removeObserver(IActionObserver o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(i);
        }

    }

    public void notifyObserver() {
        for (int i = 0; i < observers.size(); i++) {            
            IActionObserver observer = (IActionObserver) observers.get(i);          
            observer.update();
        }
    }

    public void actionClicked(View view) {
        notifyObserver();
    }

}

Solution

  • Is this your own implementation of the observer pattern? If so, you can modify the notify method, for instance:

    public void notifyObserver(IAction sender) {
        for (int i = 0; i < observers.size(); i++) {            
            IActionObserver observer = (IActionObserver) observers.get(i);  
            if (observer != sender)  
                observer.update();
        }
    }
    

    and call this as

    ActionHolder.getInstance().notifyObserver(this);
    

    Alternatively, you could add a flag in your action class:

    private bool sender = false;
    

    set the flag before notifying:

    sender = true;
    ActionHolder.getInstance().notifyObserver();
    

    and use this flag in the update:

    @Override
    public void update() {
        if (!sender) {
            getSubView().setVisibility(View.GONE);
        }
        sender = false;
    }