2012-03-01 4 views
0

У меня есть следующий наблюдатель:Проблема шаблона Java 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!"); 
    } 
} 
} 

и Наблюдаемая:

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) методы вместо того, чтобы получать сообщение один раз, я получаю то же сообщение количество раз, когда я зарегистрировал депозиты для просмотра. Как я могу это исправить?

Надеюсь, это имеет смысл. Спасибо заранее и извините, если это глупый вопрос, это первый раз, когда используется шаблон Observer.

Я думаю, эта линия может быть (несколько экземпляров?): addObserver(new Fisc(id,deposit));

+0

Я бы перешагнул ваш код в отладчике, чтобы понять, почему он не ведет себя так, как ожидалось. –

+0

Где код для класса 'Fisc'? –

+0

К сожалению, наблюдаемый был Fisc. – Fofole

ответ

2

Каждого наблюдатель (экземпляр Fisc) уведомляются всякий раз, когда Deposit экземпляра изменился. Таким образом, с вашим кодом, каждый Fisc должен посмотреть уведомление и проверить, если он составляет его депозит.

Если вы этого не хотите, то следует сделать видимым Deposit (вместо наблюдения всего банка). Затем вы можете регистрировать слушателей на отдельные депозиты.

+0

Это то, что нужно сделать, за исключением того, что на концептуальном уровне мой обман должен уведомлять вещи, но это нормально, поскольку у меня нет другого пути. – Fofole

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.

Смежные вопросы