package observer_pattern;
import java.util.ArrayList;
import java.util.List;
public abstract class Subject {
private ArrayList<Observer> observers = new ArrayList<Observer>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
//@Override:if we use notify as the method's name,the question will
//be:Cannot override the final method from Object.
public void Notify() {
for(Observer o : observers){
o.update();//Not good enough for its narrow limitation.
}
}
/***This is used for processing the "OldConcreteObserver."***/
//List is a interface and ArrayList is the class that implements it.
private List<Event> objects = new ArrayList<Event>();
public void addEvent(Object object,String methodName,Object...args) {
objects.add(new Event(object,methodName,args));
}
public void NotifyAll() throws Exception{
for(Event e:objects) {
e.invoke();//It's better than "o.update()",which improved the universality.
}
}
}
package observer_pattern;
public class ConcreteSubject extends Subject{
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
/***This is used for processing the "OldConcreteObserver."***/
@Override
public void NotifyAll() {
try {
super.NotifyAll();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
package observer_pattern;
public interface Observer {
//We use interface just because there will always be great difference
//among observers in practical use.
public abstract void update();
//The "interface" prescribe a limit to every single subclass that
//implements it in some degree,which can be seen as handicap.
//Furthermore,we can use reflection to avoid using interface.
}
package observer_pattern;
public class ConcreteObserver implements Observer{
private String name;
private String observerState;
private ConcreteSubject subject;//If one observer subscribe a lot of subjects,the
//type of "Subject" will be better,which is the superclass.
public ConcreteObserver(ConcreteSubject subject,String name) {
this.subject = subject;
this.name = name;
}
public void update() {
observerState = subject.getSubjectState();
System.out.println("The" + name +"'s situation is " + observerState);
}
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
package observer_pattern;
import java.lang.reflect.Method;
public class Event {
private Object object;
private String methodName;
private Object[] params;
private Class[] paramTypes;
/*
* java.lang.Class Instances of the class Class represent classes and interfaces
* in a running Java application. An enum is a kind of class and an annotation
* is a kind of interface. Every array also belongs to a class that is reflected
* as a Class object that is shared by all arrays with the same element type and
* number of dimensions. The primitive Java types (boolean, byte, char, short,
* int, long, float, and double), and the keyword void are also represented as
* Class objects. Class has no public constructor. Instead Class objects are
* constructed automatically by the Java Virtual Machine as classes are loaded
* and by calls to the define Class method in the class loader.
*/
public Event(Object object, String method, Object... args) {
this.object = object;
this.methodName = method;
this.params = args;
contractParamTypes(this.params);
}
private void contractParamTypes(Object[] params) {
this.paramTypes = new Class[params.length];
for (int i = 0; i < params.length; i++) {
this.paramTypes[i] = params[i].getClass();
}
}
public void invoke() throws Exception {
Method method = object.getClass().getMethod(this.methodName, this.paramTypes);
// Let's see if this function exists.
if (null == method) {
return;
}
method.invoke(this.object, this.params);// Use reflection to call functions.
}
}
package observer_pattern;
public class OldConcreteObserver {//Don't implement the interface of Subject.
private String name;
private ConcreteSubject sub;
public OldConcreteObserver(ConcreteSubject sub,String name) {
this.name = name;
this.sub = sub;
}
public void oldUpdate(String feeling) {//The premier method's name is different to "update".
System.out.println("The" + name +"'s situation is " + sub.getSubjectState());
System.out.println("The feeling is "+feeling);
}
}
package observer_pattern;
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.Notify();
/***This is used for processing the "OldConcreteObserver."***/
s.addEvent(new OldConcreteObserver(s,"W"), "oldUpdate", "happy");
s.NotifyAll();
}
}
/*
* The observer_pattern is also called Publish/Subscribe pattern,which is also
* known as notifier/observer.Java can use dynamic proxy to implement the delegation that is used directly in c#.
*/
This is a general introduction to the 23 design patterns:
https://blog.csdn.net/GZHarryAnonymous/article/details/81567214