Java观察者模式问题?

Java观察者模式问题?

问题描述:

我有以下观察:Java观察者模式问题?

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

和可观察到:

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

} 

一切正常,除了以下为suppossed:如果我使用depositValue(1,2,s)方法,而不是收到消息一次,我得到的同样的信息我注册存款的次数被观看。我怎样才能解决这个问题?

希望这是有道理的。非常感谢,如果这是一个愚蠢的问题,这是第一次使用观察者模式。

我的猜测是这条线可能(多个实例):addObserver(new Fisc(id,deposit));

+0

我会在调试器中逐句通过您的代码,以了解它为什么不像预期那样工作。 – 2012-03-01 12:27:08

+0

Fisc类的代码在哪里? – 2012-03-01 12:34:56

+0

对不起Observable是Fisc。 – Fofole 2012-03-01 12:38:45

观察者(的Fisc一个实例)每当Deposit实例已更改通知。因此,使用您的代码,每个Fisc都必须查看通知消息并检查,如果它是其存款存款。

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

+0

这是要做的事情,除了在概念层面,我的obs必须通知事情,但没关系,因为我没有其他办法。 – Fofole 2012-03-01 12:45:01

您已将所有帐户汇总在同一个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个清单:

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

注意这个类使用的BigDecimal为代表的平衡,因为它是not recommended to use floating point numbers for it