设想平时的订阅报纸业务是如何进行的,可能我的描述不是非常的准确,请原谅。一份份电子报纸我们可以看作是数据源,假设是从某处得到,那么我们要订阅它,于是你可以这样来书写代码:
输出:
package headfirst.newspaper;
public class Newspaper {
//内容
private String content;
//作者
private String author;
//....其他属性
public Newspaper(){
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//重要是这个方法,内容发生改变的时候调用
public void ContentChanged(){
subscriber1.update(content,author,....);
subscriber2.update(content,author,....);
subscriber3.update(content,author,....);
subscriber4.update(content,author,....);
}
}
这样的写法表明你是在针对具体实现编程,这样的话你在程序运行时无法改变订阅者,这样的程序难以维护和复用,比较好的做法应该是针对接口编程,把可能变化的地方抽象出来,这是面向对象设计的基本准则,于是我们可以借鉴订阅报纸来思考。
我们可以订阅某份报纸,一旦报纸出版就通知我们,并提供给我们,我们也可以取消订阅,信息资料的主动权不在订阅者手中,并不是我们不断地去问报纸要,而是有了更新才通知我们。
可以借助headfirst design中的uml图来帮助理解:
代码如下:
package headfirst.newspaper;
public interface DisplayElement {
public void display();
}
package headfirst.newspaper;
public interface Observer {
public void update(String content,String author);
}
package headfirst.newspaper;
public interface Subject {
public void register(Observer o);
public void remove(Observer o);
public void notifyObserver();
}
package headfirst.newspaper;
import java.util.ArrayList;
import java.util.Iterator;
public class Newspaper implements Subject{
//内容
private String content;
//作者
private String author;
//....其他属性
private ArrayList<Observer> observer;
public Newspaper(){
observer=new ArrayList<Observer>();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
//重要是这个方法,内容发生改变的时候调用
public void ContentChanged(String content,String author){
this.setContent(content);
this.setAuthor(author);
this.notifyObserver();
}
@Override
public void register(Observer o) {
this.observer.add(o);
}
@Override
public void remove(Observer o) {
int i=this.observer.indexOf(o);
if(i>=0){
this.observer.remove(i);
}
}
@Override
public void notifyObserver() {
System.out.println("新的内容已经发布!");
Iterator<Observer> iterator=this.observer.iterator();
while(iterator.hasNext()){
iterator.next().update(content, author);
}
}
}
package headfirst.newspaper;
public class Subscriber1 implements Observer,DisplayElement{
private String content;
private String author;
private Subject subject;
//.......
public Subscriber1(Subject subject){
this.subject=subject;
this.subject.register(this);
}
public void update(String content, String author) {
this.content=content;
this.author=author;
this.display();
}
@Override
public void display() {
System.out.println("this is subscriber1!");
System.out.println("content is "+this.content);
System.out.println("author is "+this.author);
}
public void remove(){
this.subject.remove(this);
this.subject=null;
}
public void setSubject(Subject subject){
this.subject=subject;
}
}
测试代码:
package headfirst.newspaper;
public class Test {
public static void main(String args[]){
Newspaper newspaper=new Newspaper();
Subscriber1 subscriber1=new Subscriber1(newspaper);
Subscriber2 subscriber2=new Subscriber2(newspaper);
newspaper.ContentChanged("the king of the ring", "Tolkien");
}
}
输出:
新的内容已经发布!
this is subscriber1!
content is the king of the ring
author is Tolkien
this is subscriber2!
content is the king of the ring
author is Tolkien
主要内容来自headfirst design pattern,感谢这本书