设计模式------观察者模式(Oberserver Pattern)

 设计模式------观察者模式(Oberserver Pattern)

    定义:观察者模式-在对象之间定义一对多的依赖。这样以来,一个对象改变状态时,依赖它的对象都会收到通知,并自动更新。

    OO设计的的思想里,我们强调,我们的设计总是在为对象之间的交互的松耦合而努力。观察者模式,正是在一对多的依赖中,寻找一种松耦合的实现方式。我们在日常生活中,经常会遇到这种情况,就是某个对象拥有某些状态,而其它对象都需要使用这些状态,从而执行某些行为。比如,在一个数据控制中心,有一个装置来负责采集数据,并把数据实时的告知其它的部分,这些部门需要利用这些数据。因此,这就是一个一对多的依赖关系。假设我们以卫星控制系统来描述这个模式。

    假设系统的行为为:有一个数据采集中心,负责获取卫星的实时数据:经度,纬度,飞行时常。

数据采集中西负责把及时采集到的数据通知其它部门,假设有两个部门,一个负责实时显示卫星的当前状态,另外一个部门,负责通过接收到的数据进行计算,并输出下一步的控制信号。并且,该系统还不够完善,可能会增加新的部门,该部门也需要利用卫星的实时数据,做其它的工作。

   根据以上的系统需求,我们可以知道,这是一个一对多的关系,并且,需要系统有很好的扩展性,即系统对象之间的耦合性要小。那我们怎么来实现呢?

   系统有一个数据采集中心,我们需要来设计一个类来描述这个数据采集中心,假设叫做SatelliteData,

那么显示部门也用一个类DisplayBoard类以及计算部门也用一个类Calculate来描述。类SatelliteData定义如下所示:

class SatelliteData

{

 float longitude;

 float latitude;

 float timeLast;

 public float getLongitude()

{

 ……

}

public float getLatitude()

{

……

}

public float getTimeLast()

{

……

}

public setChange()

{

longitude=getLongitude();

latitude=getLatitude();

timeLast=getTimeLast();

displayBoard.update(longitudu,latitude,timeLast);

calculate.update(longitudu,latitude,timeLast);

}

}

   其中displayBoard是类DisplayBoard的对象,calculateCalculate的对象。我们来看看这段代码,实际上违背了我们在策略模式中一再强调的面向接口编程的思想,红色部分的代码是面向实现的,针对一个个的具体需要用到这些状态的对象,发送通知。这样,如果再增加新的使用对象,那就需要修改SatelliteDate类的代码,并且,这样造成的耦合性很大。

   那我们用观察者模式如何来解决这个问题呢?观察者模式定义了一对多的依赖,其中“一”被称作主题,而“多”被称作观察者。观察者通过注册的方式来订阅主题,当不需要的时候,再通过主题取消订阅。这样,多个观察者通过订阅的方式共享主题里的内容。当主题内容改变的时候,需要动态的通知观察者,以便他们即使做出响应。

   在观察者模式中,主题实现了Subject 接口,Subject接口主要定义了三个方法,即注册观察者,通知观察者当前状态以及删除某个观察者。

  定义如下:

  interface Subject

  {

   public void registerOberserver(Oberserver o);

   public void notifyOberservers(Oberserver o);

   public void deleteOberserver(Oberserver o); 

  }

在各个方法的参数中,Oberserver是观察者接口,具体的观察者实现该接口,这样,在这里,我们体现了面向接口编程的思想。

观察者对象需要实现Oberserber接口,这个接口主要定义了更新的方法,update();这个方法主要是为了主题在更新状态是调用,这样在面向接口编程中,主题只关心接口实现的方法,具体由哪个类实现的,主题并不关心。我们来看相关的类图.

由类图可以看倒,SatelliteData类实现了Subject接口,而DisplayBoard类和Calculate类也分别实现了Oberserver接口,并且SatelliteData拥有多个注册的观察者,观察者共用同一个主题。代码如下:

//主题接口定义

interface Subject

{

public void registerOberserver(Oberserver o);

public void notifyOberservers(Oberserver o);

public void deleteOberserver(Oberserver o);

}

//观察者接口定义

interface Oberserver

{

public void update(float longtitude,float latitude,float lastTime);

}

//类卫星数据定义

class SatelliteData

{

 float longitude;

 float latitude;

 float timeLast;

ArrayList oberservers;//注册的观察者列表

public SatelliteDate()

{

oberservers=new ArralyList();

}

 public float getLongitude()

{

 ……

}

public float getLatitude()

{

……

}

public float getTimeLast()

{

……

}

public setChange()

{

longitude=getLongitude();

latitude=getLatitude();

timeLast=getTimeLast();

notifyOberservers();

}

public void registerOberserver(Oberserver o)

{

oberservers.add(o);

}

public void deleteOberserver(Oberserver o)

{

int i=Oberservers.indexOf(o);

oberservers.remove(i);

}

public void notifyOberservers()

{

longtitude=getLongtitude();

latitude=getLatitude();

timeLast=getTimeLast();

 for(int i=0;i<oberservers.size();i++)

  {

   Oberserver oberserver=(Oberserver)oberservers.get(i);

   oberserber.update(longitude,latitude,timeLast);

}

}

}

//显示部门类

class DisplayBoard  implements Oberserver

{

SatelliteDate data;

public DisplayData(SatelliteDate data)

{

this.data=data;

}

 public void update(float longtitude,float latitude,float timeLast)

{

 Syste.out.println("经度"+longtitude +"纬度:"+latitude+"持续时长"+timeLast);

 

}

//计算类

class Calculate implements Oberserver

{

 

SatelliteDate data;

public DisplayData(SatelliteDate data)

{

this.data=data;

}

 

 public void update(float longtitude,float latitude,float timeLast)

{

 //这是计算过程 

}

}

 

观察者模式总结:

1,在面向对象设计过程中,依赖关系必不可少,我们经常在为对象间的松耦合设计而努力,这是我们进行OO设计的又一个准则,除了面向接口编程以外,还需要的是把是一个变为有一个(is a to has a)。

2,观察者模式的适用范围,就如定义所言,适用于一对多的依赖关系,一个对象状态的改变影响所有其它对象,比如在银行系统中,客户帐户的利息的计算是依赖于银行的利率的,那银行的利率的改变,必须由银行象所有的客户通知,从而利息的计算结果也会发生变化。这里,银行相当于一个主题,银行客户就是观察者来订阅这个主题。可以在这里应用观察者模式。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值