4

观察者模式中的观察者是否总是必须观察相同类型的对象?如果 ONE Observer 观察完全不相关的不同类型的类的不同对象,可以吗?

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


如果我观察到多个不相关的类型,那么我将不得不使用 instanceof() 方法来检查通知观察者的 Observable 的类。但是,根据此链接,这似乎是一种不好的方法 - 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() 是否安全?

还有其他选择吗?

4

2 回答 2

3

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

import java.util.Observable;

public abstract class DashboardDataSource extends Observable {

    public abstract int getLevel();
}

Then you have two classes that inherit from DashboardDataSource (actually you have as many as you need, I'm just using two as an example):

public class FuelLevel extends DashboardDataSource {

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

And

public class BatteryLevel extends DashboardDataSource { 

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

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

You could then have a Dashboard like so:

public class Dashboard implements Observer {

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

    }
}

In this case, you just cast the Observable o to a DashboardDataSource and call the implementation of its abstract method, which will be specific to whatever DashboardDataSource is making the notification to your Dashboard (in this example a FuelLevel or BatteryLevel)

于 2013-03-31T00:47:16.297 回答
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..
于 2013-03-31T00:43:26.767 回答