- 观察者模式底层实现
- 使用java.util.Observable,java.util.Observer实现观察者模式
优点:
1:观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
2:观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
3:观察者模式支持广播通信,观察目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
4:观察者模式满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。
缺点:观察者之间有过多的细节依赖,运行效率低,程序复杂度变高。
主要用于以下情况:
观察者模式底层实现
创建观察者接口:
/**
* 观察者接口
*/
public interface Observer {
void update(Subject subject);
}
创建主题对象:
import java.util.ArrayList;
import java.util.List;
/**
* 主题对象
*/
public class Subject {
//存放观察者对象
protected List<Observer> list = new ArrayList<Observer>();
//新增观察者对象
public void register(Observer observer) {
list.add(observer);
}
//删除观察者对象
public void remove(Observer observer) {
list.remove(observer);
}
//通知所有的观察者更新状态
public void notifyAllObservers() {
for (Observer observer : list) {
observer.update(this);
}
}
}
创建具体主题对象:
/**
* 具体主题对象
*/
public class ConcreteSubject extends Subject {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
//主题对象值发生变化通知所有观察者
this.notifyAllObservers();
}
}
创建观察者对象:
/**
* 观察者对象
* 头条新闻
*/
public class ObserverHeadline implements Observer {
private String content;
@Override
public void update(Subject subject) {
content = ((ConcreteSubject) subject).getContent();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
调用:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
/**
* 这是调用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建一个主题对象
ConcreteSubject concreteSubject = new ConcreteSubject();
//创建观察者对象,比如三个
ObserverHeadline headline1 = new ObserverHeadline();
ObserverHeadline headline2 = new ObserverHeadline();
ObserverHeadline headline3 = new ObserverHeadline();
//新增观察者对象
concreteSubject.register(headline1);
concreteSubject.register(headline2);
concreteSubject.register(headline3);
Log.d("TAG", "------------------------------------");
//更改状态
concreteSubject.setContent("湖人总冠军!");
Log.d("TAG", headline1.getContent() + "");
Log.d("TAG", headline2.getContent() + "");
Log.d("TAG", headline3.getContent() + "");
Log.d("TAG", "------------------------------------");
//状态再更改
concreteSubject.setContent("火箭总冠军!");
Log.d("TAG", headline1.getContent() + "");
Log.d("TAG", headline2.getContent() + "");
Log.d("TAG", headline3.getContent() + "");
}
}
结果:使用java.util.Observable,java.util.Observer实现观察者模式
创建主题对象,并且继承java.util.Observable:
import java.util.Observable;
/**
* 主题对象
*/
public class ConcreteSubject2 extends Observable {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
setChanged(); //表示目标对象已发生变化
notifyObservers(content);//通知所有观察者
}
}
创建观察者对象,并且实现java.util.Observer :
import java.util.*;
/**
* 观察者对象
* 音乐新闻
*/
public class ObserverMusic implements java.util.Observer {
private String content;
@Override
public void update(Observable observable, Object o) {
content = ((ConcreteSubject2) observable).getContent();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
调用:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
/**
* 这是调用者
*/
public class MainActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConcreteSubject2 concreteSubject2 = new ConcreteSubject2();
ObserverMusic music1 = new ObserverMusic();
ObserverMusic music2 = new ObserverMusic();
ObserverMusic music3 = new ObserverMusic();
concreteSubject2.addObserver(music1);
concreteSubject2.addObserver(music2);
concreteSubject2.addObserver(music3);
Log.d("TAG", "------------------------------------");
//更改状态
concreteSubject2.setContent("周杰伦出新专辑了!");
Log.d("TAG", music1.getContent() + "");
Log.d("TAG", music2.getContent() + "");
Log.d("TAG", music3.getContent() + "");
Log.d("TAG", "------------------------------------");
//再更改状态
concreteSubject2.setContent("赵雷出新专辑了!");
Log.d("TAG", music1.getContent() + "");
Log.d("TAG", music2.getContent() + "");
Log.d("TAG", music3.getContent() + "");
}
}
结果:已完成测试!有不对的地方欢迎指出,感恩。