1、设计思路
观察者模式又称为发布/订阅(Publish/Subscribe)模式。观察者模式提供了一种对象设计,让主题和观察者之间松耦合。主题只知道观察者实现了某个接口(也就是Observer接口)。主题不需要知道观察者具体类是谁、做了些什么或其他任何细节。主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者和删除观察者。有新类型的观察者出现时,主题的代码不需要修改。
2、UML类关系图
3、代码实现
最形象的栗子是:杂志订阅,杂志是主题,观察者是订阅者。当出版新杂志时候,这个事件会自动通知所有的订阅者。根据OO基本原则,应该针对接口编程,主题和订阅者一般都作为接口。
/**
* 出版社主题接口对象
*
*/
public interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObservers();
}
/**
* 具体的出版社对象
*
*/
public class ConcreteSubject implements Subject {
private Boolean changeflag;
private List<Observer> obsList = new ArrayList<>();
private String bookname;
private String author;
@Override
public void registerObserver(Observer observer) {
obsList.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if(obsList.contains(observer)){
obsList.remove(observer);
}
}
@Override
public void notifyObservers() {
if(changeflag){
for (Observer observer : obsList) {
observer.update(bookname,author);
}
}
}
public void publishBook(String bookname,String author,boolean changeflag){
this.bookname = bookname;
this.author = author;
this.changeflag = changeflag;
notifyObservers();
}
public Boolean getChangeflag() {
return changeflag;
}
public void setChangeflag(Boolean changeflag) {
this.changeflag = changeflag;
}
public List<Observer> getObsList() {
return obsList;
}
public void setObsList(List<Observer> obsList) {
this.obsList = obsList;
}
public String getBookname() {
return bookname;
}
public void setBookname(String bookname) {
this.bookname = bookname;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
/**
* 观察者
*
*/
public interface Observer {
public void update(String bookname, String author);
}
/**
* 具体的观察者
*
*/
public class ConcreteObserver implements Observer{
private ConcreteSubject concreteSubject;
private String readerName;
public ConcreteObserver(ConcreteSubject subject, String reader) {
super();
this.concreteSubject = subject;
this.readerName = reader;
subject.registerObserver(this);
}
@Override
public void update(String bookname,String author) {
System.out.println("订阅者获得一本新书《"+bookname+"》,作者是:"+author);
}
public ConcreteSubject getConcreteSubject() {
return concreteSubject;
}
public void setConcreteSubject(ConcreteSubject concreteSubject) {
this.concreteSubject = concreteSubject;
}
public String getReaderName() {
return readerName;
}
public void setReaderName(String readerName) {
this.readerName = readerName;
}
}
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver(subject,"小明");
ConcreteObserver observer2 = new ConcreteObserver(subject,"小星");
ConcreteObserver observer3 = new ConcreteObserver(subject,"小宇");
ConcreteObserver observer4 = new ConcreteObserver(subject,"小志");
subject.publishBook("追风筝的人", "啊啊", true);
subject.publishBook("深入理解JVM", "嗯嗯", true);
}
测试结果: