Java观察者模式问题?

时间:2012-03-01 12:21:38

标签: java observer-pattern

我有以下观察员:

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!");
    }
}
}

和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);
    }

}

除了以下内容之外,所有内容都起到了假设作用:如果我使用depositValue(1,2,s)方法而不是获取消息一次,我会收到相同的消息,即我已经注册了要观看的存款的次数。我该如何解决这个问题?

  

希望这是有道理的。在此先感谢,如果这是一个愚蠢的问题,这是第一次使用Observer Pattern。

我的猜测是这行(多个实例?):addObserver(new Fisc(id,deposit));

2 个答案:

答案 0 :(得分:2)

每当Fisc实例发生更改时,都会通知每个观察者(Deposit的实例)。因此,对于您的代码,每个Fisc都必须查看通知消息并检查是否与 存款有关。

如果您不想要,那么您应该Deposit观察(而不是观察整个银行)。然后,您可以将听众注册到个人存款。

答案 1 :(得分:1)

您已将所有帐户汇总在同一个Observable对象中,这就是您获得的原因 每个帐户都会收到一次通知。

更好的模型可能是引入Account课程并制作Observable 我建议像:

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();
    }
}

您的obs课程将包含Account s的列表:

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

请注意,此类使用BigDecimal表示余额,因为它是not recommended to use floating point numbers for it