观察者模式的定义:观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
public class AReporter {
private Media newspaper;
private Media wechat;
private String news;
public AReporter(Newspaper newspaper, Wechat wechat){
this.newspaper = newspaper;
this.wechat = wechat;
}
public void notice(){
newspaper.publish(this.news);
wechat.publish(this.news);
}
public void setNews(String news) {
this.news = news;
}
}
public interface Media {
public void publish(String news);
}
public class Newspaper implements Media {
@Override
public void publish(String news) {
System.out.println(news);
}
}
public class Wechat implements Media {
@Override
public void publish(String news) {
System.out.println(news);
}
}
由于A记者和媒体的耦合度较高,如果有变动发生,例如,在报纸和微信上发布新闻后,还需在微博上发布消息,此时将不得不对A记者类进行修改,违反了开闭原则,因此需要降低A记者和媒体之间的耦合度
public class AReporter {
private List<Media> medias = new LinkedList<>();
private String news;
public void addMedia(Media media){
medias.add(media);
}
public void removeMedia(Media media){
medias.remove(media);
}
public void notice(){
for(Media media : medias)
media.publish(this.news);
}
public void setNews(String news) {
this.news = news;
}
}
A记者和媒体之间的耦合度降低了(由组合变为关联),单来的好处就是A记者现在的扩展性很好,无论添加媒体,删除媒体,都不需要对A记者类进行修改
根据依赖倒置原则,我们很容易就会想到从A记者类抽象出记者接口
上面的示例比较简单,A记者类单向依赖媒体接口,有时候我们会遇到一些比较复杂的情况:A记者和媒体接口互相依赖
public interface Media {
public void register(AReporter areporter);
public void publish(String news);
}
public class Newspaper implements Media {
@Override
public void register(AReporter areporter){
areporter.addMedia(this);
}
@Override
public void publish(String news) {
System.out.println(news);
}
}
public class Wechat implements Media {
@Override
public void register(AReporter areporter){
areporter.addMedia(this);
}
@Override
public void publish(String news) {
System.out.println(news);
}
}
根据依赖倒置原则,我们不能在抽象的媒体类中耦合具体的A记者类,所以此时从A记者类抽象出记者接口是十分必要的,修改后的完整类结构如下图
现在的类图和观察者模式的定义就完全一致了