Observer Pattern
Tags: behavioral, pattern, designpatterns, java
Published: 2020-09-28 04:34:51

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ff1rf937aubucths6cqo.png)

#Participants#
* Subject: knows its observers. Any number of Observer objects may observe a subject. Provides an interface for attaching and detaching Observer objects.
* ConcreteSubject: stores state of interest to ConcreteObserver. Sends a notification to its observers when its state changes
* Observer: defines an updating interface for objects that should be notified of changes in a subject.
* ConcreteObserver: maintains a reference to a ConcreteSubject object. Stores state that should stay consistent with the subject's. Implements the Observer updating interface to keep its state consistent with the subject's.

#Code#
```java
public class Main {

	public static void main(String[] args) {
		ConcreteSubject s = new ConcreteSubject();
		s.attach(new ConcreteObserver(s, "X"));
		s.attach(new ConcreteObserver(s, "Y"));
		s.attach(new ConcreteObserver(s, "Z"));
		s.setSubjectState("ABC");
		s.notifyObservers();
	}
}

public class Subject {

	private List<Observer> observers = new ArrayList<>();

	public void attach(Observer observer) {
		observers.add(observer);
	}

	public void detach(Observer observer) {
		observers.remove(observer);
	}

	public void notifyObservers() {
		for (Observer o : observers) {
			o.update();
		}
	}
}

public class ConcreteSubject extends Subject {
	
	private String subjectState;

	public String getSubjectState() {
		return subjectState;
	}

	public void setSubjectState(String subjectState) {
		this.subjectState = subjectState;
	}    
}

public interface Observer {

	void update();
}

public class ConcreteObserver implements Observer {

	private String name;
	private ConcreteSubject subject;

	public ConcreteObserver(ConcreteSubject subject, String name) {
		this.subject = subject;
		this.name = name;
	}

	@Override
	public void update() {
		String observerState = subject.getSubjectState();
		System.out.println("Observer " + name + " state is " + observerState);
	}
}
```

#Output#
```
Observer X state is ABC
Observer Y state is ABC
Observer Z state is ABC
```

#Java Builtin Observer#
```java
public class Main {

	public static void main(String[] args) {
		ConcreteSubject s = new ConcreteSubject();
		s.addObserver(new ConcreteObserver(s, "X"));
		s.addObserver(new ConcreteObserver(s, "Y"));
		s.addObserver(new ConcreteObserver(s, "Z"));
		s.setSubjectState("ABC");
		s.notifyObservers();
	}
}

import java.util.Observable;

public class ConcreteSubject extends Observable {
	
	private String subjectState;

	public String getSubjectState() {
		return subjectState;
	}

	public void setSubjectState(String subjectState) {
		this.subjectState = subjectState;
		setChanged();
	}
    
}

import java.util.Observable;
import java.util.Observer;

public class ConcreteObserver implements Observer {

	Observable subject;
	private String name;
	
	public ConcreteObserver(Observable subject, String name) {
		this.subject = subject;
		this.name = name;
	}

	@Override
	public void update(Observable obs, Object arg) {
		if(obs instanceof ConcreteSubject) {
			ConcreteSubject observable = (ConcreteSubject)obs;
			System.out.println("Observer " + name + " state is " + observable.getSubjectState());
		}		
	}
}
```
{% github https://github.com/eidherjulian61/design-patterns no-readme %}
{% link https://dev.to/eidher/principales-patrones-de-diseno-13ao
 %}