我将初次学习设计模式的一些思维活动记录如下,如有谬论请不吝斧正。
观察者模式
定义对象之间的一对多的依赖关系,当一个对象改变状态,它的依赖者都会收到通知并自动更新
出版社是主题对象,读者们是依赖者对象。一旦出版者改变状态有了新刊,订阅者们就会 收到通知并更新自己的状态。
这就产生了依赖关系。突然一天订阅者A要退刊,他就不再是出版社的依赖者,自然不会再接受出版社的通知。
实现:包含Subject和Observer接口的类设计
建立接口(面向接口编程)
public interface Subject{
public void reqisterObserver(Observer o); //注册观察者对象
public void removeObserver(Observer o); //删除观察者对象
public void notifyObservers(); //主题状态改变时通知观察类
}
public interface Observer{
public void update(状态作为参数); //当状态改变时,主题把这些状态当作参数传进来通知观察者
}
public interface Things{ //封装观察者变化的行为,面向接口编程
public void doThing();
}
建立主题类并实现主题接口
public class Publisher implements Subject{
private ArrayLiat observers; //记录观察者
private String name1;
private String name2;
public Publisher{
observers=new ArrayList(); //构造时建立
}
//实现主题接口
public void reqisterObserver(Observer o){
observers.add(o); //面向接口编程
}
public void removeObserver(Observer o){
int i=obsrvers.indexOf(o);
if(i>0)
observers.remove(i);
}
public void notifyObservers(){
for(int i=0;i<observers.size();i++){
Observers observer=(Observer)observers.get(i); //获取观察者对象
observer.update(name1,name2); //状态做参数
}
}
//当状态是否改变,是的话调用notifyObverservers();
public void nameChanged(){
if(...)
notifyObservers();
}
//获取状态,并
public void setMeasurements(String name1,String name2){
this.name1=name1;
this.name1=name2;
nameChanged();
}
}
建立观察者类
public class reader implements Observer,Things{
private String name1;
private Subject p;
//每次初始化对象在主题对象中注册
public reader(Subject p){
this.p=p;
p.refisterObverser(this); //面向接口编程
}
//当update在主题中被调用时,把需要的状态保存下来,并执行相关处理
public void update(String name1,String name2){
this.name1=name1;
doThing();
}
//这个观察者类的行为
public void doThing(){}
}
**总结**
变化的是主题的状态、观察者的数目类型,利用两接口封装了这些变化。
面向接口编程,观察者利用主题接口注册,运行时观察者组合进主题产生了依赖关系。
主题不知道观察者具体类是谁等其他细节,只知道观察者实现了Observer接口,
利用接口通知观察者,可以改变观察者却不用改变主题,具有松耦合优点。
松耦合:两对象之间松耦合,可互相交互,不太清楚彼此的细节
第三个设计原则:为了交互对象之间的松耦合设计而努力
松耦合的设计可以建立有弹性的OO系统,因为对象间的互相依赖降到了最低所以能应对变化。
以上,主题主动推送状态。还可以由观察者通过主题主动获取,这样不用修改更新对每位观察者的调用,只需要增加get方法。
Java内置的Onserver模式支持以上两种做法(util)
主题(可观察者)继承Observable类,观察者实现Observer接口调用继承下来的addObserver()
推送状态:setChanged() 改变标志,决定是否发送通知(扩展性);notifyservers(Object arg);
接收状态:update(Observable o,Object arg);
利用java内置实现观察者主动获取状态
观察者调用所需get方法,setChanged判断后决定是否发送
public class Publisher extends observable{
private String name1;
private String name2;
public Publisher{
}
public void namesChanged(){
setChanged();
notifyObservered();
}
//设置name并判断是否要传送状态
public void setMeadurements(String name1,String name2){
this.name1=name1;
this.name2=name2;
namesChanged();
}
//get方法
public String getName1(){
return name1;
}
public String getName2(){
return name2;
}
}
public class reader implements Observer,Things{
Observable observable;
private String name1;
//构造时将reader注册成观察者
public reader(Observable observable){
this.observable=observable;
observable.addObserver(this);
}
//update方法增加Observable和数据对象作为参数
public update(Observable obs,Object arg){
if(obs instanceof Publisher){
Publisher publisher=(Publisher)obs;
this.name1=publisher.getName1();
doThing();
}
}
//reader观察者对状态的炒作
public void doThing(){}
}
Observable类的一些问题:
- 必须要继承它,但java又不支持多继承;
- 不是接口,无法自己建立实现;
- setChanged方法被保护,除非继承否则无法实例组合。
观察者模式在JDK中有很多应用,以松耦合方式在一系列对象之间沟通状态。