Java中的观察者模式 - 观察者观察不同的,不相关的类型或类?

时间:2013-03-31 00:06:37

标签: java observer-pattern instanceof

观察者模式中的Observer是否始终必须观察相同TYPE的对象?如果ONE Observer观察到完全不相关的不同类型的不同对象,这没关系吗?

示例 - Observer是CarDashBoard,Observable是FuelTank,Speedometer,EngineThermometer,CarBattery等。观察到的参数分别是fuelLevel,speed,temperatureOfEngine,powerLevel。


如果我观察到多个不相关的类型,那么我将不得不使用instanceof()方法来检查通知Observer的Observable的Class。但是,根据此链接看起来这是一种不好的方法 - http://www.javapractices.com/topic/TopicAction.do?Id=31

与instanceof - http://blog.joda.org/2007/01/java-language-dynamic-instanceof_7967.html

相关的另一个链接

所以,我认为我将使用getClass()方法,然后根据传递的Observable确定要执行的操作是什么。为此目的使用getClass()是否安全?

还有其他选择吗?

2 个答案:

答案 0 :(得分:3)

你可以使用多态。例如,假设您有一个扩展Observable的抽象类:

import java.util.Observable;

public abstract class DashboardDataSource extends Observable {

    public abstract int getLevel();
}

然后你有两个继承自DashboardDataSource的类(实际上你有多少你需要的,我只是用两个作为例子):

public class FuelLevel extends DashboardDataSource {

    public void saySomething(){
        setChanged();
        notifyObservers();
    }
    @Override
    public int getLevel() {
        // TODO Auto-generated method stub
        return 50;
    }
}

并且

public class BatteryLevel extends DashboardDataSource { 

    public void saySomething(){
        setChanged();
        notifyObservers();
    }

    @Override
    public int getLevel() {
        // TODO Auto-generated method stub
        return 20;
    }
}

然后你可以像Dashboard这样:

public class Dashboard implements Observer {

    @Override
    public void update(Observable o, Object arg) {
        DashboardDataSource d = (DashboardDataSource) o;
        System.out.println (d.getLevel());

    }
}

在这种情况下,您只需将Observable o转换为DashboardDataSource并调用其抽象方法的实现,该方法将特定于DashboardDataSource向您的Dashboard发送通知的任何内容(在此示例中为FuelLevelBatteryLevel

答案 1 :(得分:2)

不使用instanceof的原因是它是一个使用多态的黑客。它会起作用,但最好提出一个更面向对象的解决方案。使用getClass会遇到同样的问题。

我想我会创建多个观察者,分别用于FuelTank,Speedometer等,并让他们更新CarDashboard。这样的事情。

public class CarDashboard
{
    public int currentSpeed;
    public int fuelPercentage;    
    //etc...
}

public class FuelObserver extends Observer
{
   private CarDashboard dashboard;

   public FuelObserver(CarDashboard dashboard)
   {
      this.dashboard = dashboard;
   }

   public void update(Observable fuelTank, Object fuelLevel)
   {
       this.dashboard.fuelPercentage = (int)fuelLevel;
   }
}

//etc..