观察者模式:通知状态

时间:2016-11-28 19:06:07

标签: java design-patterns observer-pattern

我在互联网上看到的例子只给了Observable对象notifyObservers()方法。如果我还要将一些数据传递给观察者,以便他们知道他们是否应该对此作出反应,该怎么办?观察者模式是否允许传递数据,如:

notifyObservers(Event e)

或许观察者自己应该推动变革?喜欢也许: notifyObservers() -> call observer.update()

然后每个观察者决定新数据是否与他们相关,observable.getData()。然而,通过这种方法,我不清楚如何只获得有变化的数据,如果它完全需要的话。

编辑,示例:

说我想和经营者,客户和出租车一起打造出租车公司。根据 @Pritam Banerjee的答案,我会说出租车公司是运营商和客户之间的调解员(例如,为什么 - 客户可以通过电话或在线呼叫出租车)。然后我的操作员是主体,出租车是观察员。

Operator ---observes---> TaxiFirm

TaxiFirm(waits for client) ---notifies one---> Operator(公司选择负责哪个运营商,并将客户端传递给运营商)

Taxi ---observes all---> Operators(需要以某种方式推送数据,如果出租车被占用,则无法接受新客户)

Taxi ---notifies---> Operator(如果出租车可以接受客户,它将通知运营商,我不担心任何竞争条件,因为这个事件将被手动触发。此外,也许出租车应该通知公司而不是运营商?)

我认为TaxiFirm可能不需要将客户端传递给运营商,但考虑到现实生活,它真的是与客户交流的运营商......

我写下了我的思考过程,请帮我弄清楚这个模型的架构。

2 个答案:

答案 0 :(得分:1)

您可以将观察者设计模式中介模式一起使用,以便应用程序还可以订阅数据并将数据发布到其他相关应用程序。

有关此示例,您可以查看here

有关 Mediator设计模式的详细信息,您可以阅读此article

答案 1 :(得分:1)

当然,ObserverPattern允许您通过其notify方法传递信息。如果出租车需要客户信息,您可以通过:

observer.notify(ClientInfo info)

当然,观察者可以请求信息:

observer.notify()

void notify() {
    update();
}

两者都有可能,但是,我不会说你在这里真的有ObserverPattern。根据此模式,主题只是通知所有观察者。但你描述的是主体应该通知其中一辆出租车,等待它的响应(如果出租车已经载有乘客),然后可能通知下一辆出租车。您可以将其称为ObserverPattern的变体,但它不同。

一个简单的建议,让您开始:

类运营商:

List<Taxi> taxis;

boolean chooseTaxi(RideNumber rideNumber) {
    for (Taxi taxi : taxis) {
        boolean isAccepted = taxi.notify(this, rideNumber);
        if (isAccepted) {
           markTaxiRideAsAccepted(taxi, rideNumber);
           return true;
        }
    }
    return false; // No taxi accepted the ride.
}

班级出租车

boolean notify(Operator operator, RideNumber rideNumber) {
    if (isTaxiAlreadyCarryingPassenger()) return false;

    ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
    startClientProcess(clientInfo);

    return true;
}

注意:RideNumber只是出租车后来用来向运营商请求客户信息的识别号码。您可以通过notify方法发送clientInfo,但是所有的出租车都会获得此信息,这对于安全性来说很糟糕,并且可能会造成混淆(发送不应使用的信息)。

<强>更新

如果这是家庭作业,你必须使用确切的ObserverPattern,你可以这样做:

类运营商:

List<Taxi> taxis;

void notifyAllTaxis(RideNumber rideNumber) {
    for (Taxi taxi : taxis) {
        taxi.notify(this, rideNumber);            
        }
    }        
}

ClientInfo getClientInfo(this, rideNumber) {
    if (isRideNotYetAccepted(rideNumber)) {
        markRideAsAccepted(taxi, rideNumber);
        return getClientInfo(rideNumber);
    }
    else return null;
}

班级出租车

void notify(Operator operator, RideNumber rideNumber) {
    if (!isTaxiAlreadyCarryingPassenger()) {

        ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
        if (clientInfo != null) startClientProcess(clientInfo);
    }
}