简体   繁体   English

Java观察者模式问题?

[英]Java Observer Pattern issue?

I have the following Observer: 我有以下观察者:

public class Fisc implements Observer {
double value1;
double value2;
private static HashMap<String, Deposit> accounts=new HashMap<String,Deposit>();
public Fisc(String cnp,Deposit deposit) {

    System.out.println("\n*******Observer*******Watching account:"+id);
    accounts.put(id, deposit);

}

public void update(Observable obj, Object arg) {
    if (arg instanceof Deposit) {
        value1 =((Deposit) arg).getvalue1();
        value2=((Deposit) arg).getvalue2();
        System.out.println("\n*******Observer*******value1 current value:"+value1);
        System.out.println("*******Observer*******value2 current value:"+value2);
    } else {
        System.out.println("Observable error!");
    }
}
}

and the Observable: 和可观察的:

import java.util.HashMap;
import java.util.Observable;


public class obs extends Observable {

    private static HashMap<String, Deposit> accounts;

    private static obs instance;

    private obs(HashMap<String,Deposit> accounts){
        obs.accounts=accounts;
    }

    public static obs getInstance(){
        if (instance==null){
            return new obs(new HashMap<String,Deposit>());
        }
        else return instance;
    }

        // ... some unimportant other stuff

    public void depositvalue1(String id,double value1){
        Deposit deposit=accounts.get(id);
        deposit.addvalue1(value1);

        if(deposit.isWatchedByFisc()){
            notifyFisc(deposit);
        }
        System.out.println("obs:Deposited "+value1+ " value1 to account:"+id+"!");
        System.out.println("obs:Current value1 in account:"+deposit.getvalue1());
    }

    public void depositvalue2(String id,double value2){
        Deposit deposit=accounts.get(id);
        deposit.addvalue2(value2);

        if(deposit.isWatchedByFisc()){
            notifyFisc(deposit);
        }

        System.out.println("obs:Deposited "+value2+" value2 to account:"+id+"!");
        System.out.println("obs:Current value1 in account:"+deposit.getvalue2());
    }

    public void depositValues(String id,double value1,double value2){
        Deposit deposit=accounts.get(id);
        deposit.addvalue1(value1);
        deposit.addvalue2(value2);

        if(deposit.isWatchedByFisc()){
            notifyFisc(deposit);
        }

        System.out.println("obs:Deposited "+value1+ " value1 and "+value2+" value2 to account"+id+"!");
        System.out.println("obs:Current value1 in account:"+deposit.getvalue1());
    }

    public void watchAccount(String id){
        Deposit deposit=accounts.get(id);
        deposit.setWatchedByFisc(true);
        addObserver(new Fisc(id,deposit));
    }

    public void stopWatchAccount(String id){
        accounts.get(id).setWatchedByFisc(false);
        System.out.println("obs:Account "+id+" is no longer watched by Fisc!");
    }

    public void notifyFisc(Deposit deposit){
        setChanged();
        notifyObservers(deposit);
    }

}

Everything works as suppossed except the following: If I use the depositValue(1,2,s) methods instead of getting the message once, I get the same message the number of times I have registered deposits to be watched. 除以下各项外,所有内容均按假定的方式工作:如果我使用depositValue(1,2,s)方法而不是一次获取消息,则我得到注册要观看的存款的次数也得到相同的消息。 How can I fix this? 我怎样才能解决这个问题?

Hope this makes sense. 希望这是有道理的。 Thanks in advance and sorry if this is a stupid question this is the first time using Observer Pattern. 在此先感谢您,如果这是一个愚蠢的问题,对不起,这是第一次使用观察者模式。

My guess is this line maybe(multiple instances?): addObserver(new Fisc(id,deposit)); 我的猜测是,这行可能是(多个实例?): addObserver(new Fisc(id,deposit));

Every observer (an instance of Fisc ) is notified whenever a Deposit instance has changed. 每当Deposit实例发生更改时,就会通知每个观察者( Fisc一个实例)。 So with your code, every Fisc has to look at the notification message and check, if it is about its deposit. 因此,使用您的代码,每个Fisc都必须查看通知消息并检查是否有关存款。

If you don't want that, then you should make the Deposit observable (instead of observing the whole bank ). 如果您不希望这样做,则应使“ Deposit可观察(而不是观察整个银行 )。 Then you can register listeners to individual deposits. 然后,您可以注册个人存款的监听器。

You have lumped together all accounts in the same Observable object and that's why you get notified once for each account. 您已经将所有帐户集中在同一个Observable对象中,这就是为什么每个帐户都会收到一次通知的原因。

A better model would probably be to introduce an Account class and make that Observable . 更好的模型可能是引入Account类并使该Observable成为可能。
I suggest something like: 我建议类似:

public class Account extends Observable {

    private String id;    
    private BigDecimal balance = new BigDecimal("0.0");

    public Account(String id) {
      this.id = id;
    }

    public BigDecimal getBalance() {
        return balance;
    }

    public void deposit(BigDecimal amount) {
        balance = balance.add(amount);
        notifyObservers();
    }

    public void withdraw(BigDecimal amount) {
        balance = balance.subtract(amount);
        notifyObservers();
    }
}

Your obs class would then contain a list of Account s: 然后,您的obs类将包含Account的列表:

private Map<String, Account> accounts = new HashMap<String, Account>();

Note that this class uses BigDecimal for representing the balance, since it is not recommended to use floating point numbers for it . 请注意,此类不建议使用浮点数 ,因为此类使用BigDecimal表示余额。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM