Связь между BO и GUI разорвана. Что делать? - PullRequest
0 голосов
/ 01 марта 2010

У меня есть несколько точек (остановок автомобилей) для отображения на временном графике. Эти точки связаны между собой линиями. Точки + Линии представляют График (это расписание автомобиля). График можно изменить, перемещая CarStops во времени с помощью мыши.

Я решил использовать Точки и Линии в качестве элементов управления (подумал, что будет легче перемещать их по панелям).

У меня есть два уровня бизнес-объектов - Real BO (CarStop) и GUI Control (CarStopControl). Затем я связываю CarStop (время, станция) с CarStopControl (X, Y) - CarStopControl подписывается на события CarStop.Moved.

Наконец, у объекта Car есть CarStop с.

  • Как мне переместить элементы управления? Просто: Определить движение мыши на панели и вычислить dX, преобразовать dX в dTime Car.Move(dTime) - перемещает все CarStops. Когда CarStop переместился, отправьте событие на CarStopControl, и последний изменит свои координаты. Таким образом CarStopControl похоже следует за движениями мыши.

Это все.


Проблема появилась, когда в Car.Move возникла необходимость воссоздать коллекцию CarStop - связи между CarStopControl и CarStop явно устарели, автомобиль BO Car и CarStop не заботится и даже не знает о CarStopControl с.

Аналогичная ситуация возникает, когда сам Car может быть заменен на new Car.

Были ли у кого-нибудь подобные ситуации? Есть ли «обходной путь» + - быстро решить эту проблему?

Спасибо.

1 Ответ

0 голосов
/ 01 марта 2010

Моя первая идея - ввести дополнительный уровень косвенности. Вместо реальных CarStop и Car вашими элементами управления могут быть подписчики на прокси-объекты (реализующие тот же интерфейс), которые затем, в свою очередь, узнают своего «настоящего» собеседника и могут обновлять ссылку на его собеседника, когда последний заменяется на новый.

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 заменяется другим, новый объект просто берет идентификатор своего предшественника и использует его в своих сообщениях об обновлении:

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
...