以下内容摘抄于《C# 大话设计模式》
观察者模式(Observer):定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
结构图如下:
代码如下:
package com.schema.observer;
import java.util.ArrayList;
import java.util.List;
public abstract class Subject {
private List<Observer> observers = new ArrayList<Observer>();
// 增加观察者
public void Attach(Observer observer){
observers.add(observer);
}
// 移除观察者
public void Detach(Observer observer){
observers.remove(observer);
}
//通知
public void Notify(){
for(Observer observer : observers){
observer.Update();
}
}
}
package com.schema.observer;
public abstract class Observer {
public abstract void Update();
}
package com.schema.observer;
public class ConcreteSubject extends Subject {
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
package com.schema.observer;
public class ConcreteObserver extends Observer {
private String name;
private String observerState;
private ConcreteSubject subject;
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
public ConcreteObserver(ConcreteSubject subject, String name){
this.subject = subject;
this.name = name;
}
public void Update(){
observerState = subject.getSubjectState();
System.out.println("观察者" + name + "$的新状态是" + observerState);
}
public static void main(String[] args){
ConcreteSubject s = new ConcreteSubject();
s.Attach(new ConcreteObserver(s, "Lizz"));
s.Attach(new ConcreteObserver(s, "H"));
s.Attach(new ConcreteObserver(s, "G"));
s.setSubjectState("ABC");
s.Notify();
}
}
日常生活中常常有人订阅杂志,我们以此为例。假设有一个抽象的杂志类和一个实现了抽象杂志类的One类。以及有一个订阅接口和实现了订阅接口的Customer类。
package com.schema.observer.magazine;
import java.util.LinkedList;
import java.util.List;
public abstract class Magazine {
protected List<ISubScribe> customers = new LinkedList<ISubScribe>();
// 读者订阅杂志
public void Subscribe(ISubScribe customer){
customers.add(customer);
}
// 读者退订杂志
public void Unsubscribe(ISubScribe customer){
customers.remove(customer);
}
// 向订阅者发送杂志
public void SendMagazine(){
System.out.println("新一期的杂志又和大家见面了:");
for(ISubScribe custome : customers){
custome.GetMessageInfo();
}
}
// 杂志内容
protected String contextInfomation;
public abstract void SetMagazineContext(String context);
}
package com.schema.observer.magazine;
public class One extends Magazine {
public void SetMagazineContext(String context){
contextInfomation = context;
}
}
package com.schema.observer.magazine;
public interface ISubScribe {
// 获取杂志内容信息
public void GetMessageInfo();
}
package com.schema.observer.magazine;
public class Customer implements ISubScribe {
private Magazine magazine;
private String name;
public Customer(Magazine magazine,String name){
this.magazine = magazine;
this.name = name;
}
public void GetMessageInfo(){
System.out.println( name + " 获取最新一期杂志,内容:" + magazine.contextInfomation);
}
public static void main(String[] args){
Magazine magazine = new One();
ISubScribe c1 = new Customer(magazine, "tom");
ISubScribe c2 = new Customer(magazine, "jerry");
ISubScribe c3 = new Customer(magazine, "lucy");
// 客户订阅杂志
magazine.Subscribe(c1);
magazine.Subscribe(c2);
magazine.Subscribe(c3);
// 填充杂志内容
magazine.SetMagazineContext("Hi,Big Men.");
// 向客户发送杂志内同
magazine.SendMagazine();
// 客户c1退订杂志
magazine.Unsubscribe(c1);
// 更新杂志内容
magazine.SetMagazineContext("Hey.Guys.");
//发送最新一期的内容
magazine.SendMagazine();
}
}