0

我有一些点(汽车站)要在时间图上表示。这些点之间通过线连接起来。Points + Lines 代表一个图表(即汽车时间表)。可以通过用鼠标及时移动 CarStops 来修改图表。

我决定将点和线实现为控件(认为在面板上移动它们会更容易)。

我有两个业务对象层——Real BO ( CarStop) 和 GUI Control ( CarStopControl)。CarStop然后我将(Time, Station)关联到CarStopControl(X, Y) - CarStopControl 订阅 CarStop.Moved 事件。

最后,一个Car对象有一些CarStops。

  • 如何移动控件?很简单:检测面板上的鼠标移动并计算dX、转换- 移动所有dXdTime Car.Move(dTime)CarStop。移动时CarStop,将事件发送到CarStopControl,后者更改其坐标。这种方式CarStopControl似乎跟随鼠标移动。

这是所有的了。


Car.Move当需要重新创建CarStop集合时,问题就出现了——CarStopControl并且CarStop显然已经过时,汽车 BOCarCarStop不关心甚至不知道CarStopControls 之间的链接。

类似的情况是当Car自身可以被替换为new Car.

有人遇到过类似情况吗?是否有 +- 的“解决方法”快速解决此问题?

谢谢。

4

1 回答 1

0

我的第一个想法是引入一个额外的间接级别。您的控件可以是代理对象(实现相同的接口)的订阅者,而不是真实对象CarStopCar对象,然后代理对象又知道他们的“真实”伙伴,并且能够在后者被替换为新伙伴时更新对他们的伙伴的引用.

interface ICarStop {
    void addObserver(CarStopObserver observer);
    void removeObserver(CarStopObserver observer);
}

class CarStopControl implements CarStopObserver {
    public void update (ICarStop obj, Object arg) {
        // ...
    }
}

class CarStopProxy implements ICarStop {
    ICarStop original;
    public CarStopProxy(ICarStop original) {
        this.original = original;
    }
    public void setOriginal(ICarStop original) {
        this.original = original;
    }
    public void addObserver(CarStopObserver observer) {
        // ...
    }
    public void removeObserver(CarStopObserver observer) {
        // ...
    }
    public void notifyObservers(Object object) {
        // iterate through observers an update each
    }
}

class CarStop implements ICarStop {
    CarStopProxy proxy;
    public CarStop(CarStopProxy proxy) {
        this.proxy = proxy;
    }
    public CarStop(CarStop other) {
        // copy all properties
        this.proxy = other.proxy;
    }
    public CarStopProxy getProxy() {
        return proxy;
    }
    public void setProxy(CarStopProxy proxy) {
        this.proxy = proxy;
    }
    public void handleChange() {
        proxy.notifyObservers(...);
    }
}

现在,当您需要替换 CarStop 对象时,您可以编写:

CarStop newCarStop = new CarStop(oldCarStop);
// update all references to point to the new object
oldCarStop.setProxy(null);

另一种可能性是引入一个Mediator,它能够通过某种标识符来识别模型对象(不同于它们的具体地址/引用,因为它可以改变)。在这种情况下,当一个CarStop对象被另一个对象替换时,新对象只是接管其前身的 ID,并在其更新消息中使用它:

class CarStop implements ICarStop {
    Mediator mediator;
    Long id;
    public CarStop(Mediator mediator) {
        this.mediator = mediator;
    }
    public CarStop(CarStop other) {
        // copy all properties
        this.mediator = other.mediator;
    }
    public void handleChange() {
        mediator.notifyObservers(id, ...);
    }
}

CarStop newCarStop = new CarStop(oldCarStop);
// update all references to point to the new object
于 2010-03-01T15:51:31.447 回答