2012-03-01 132 views
0

我有以下觀察: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

回答

2

觀察者(的Fisc一個實例)每當Deposit實例已更改通知。因此,使用您的代碼,每個Fisc都必須查看通知消息並檢查,如果它是其存款存款。

如果你不想那樣,那麼你應該使Deposit觀察(而不是觀察整個銀行)。然後你可以註冊聽衆個人存款。

+0

這是要做的事情,除了在概念層面,我的obs必須通知事情,但沒關係,因爲我沒有其他辦法。 – Fofole 2012-03-01 12:45:01

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個清單:

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

注意這個類使用的BigDecimal爲代表的平衡,因爲它是not recommended to use floating point numbers for it