观察者模式类(JAVA)

时间:2014-09-28 01:10:51

标签: java

我坚持这个任务。我给了一个抽象的Observer类,其中只有一个构造函数,一个带参数/参数的构造函数。 (参见下文)

public static void main(String[] args) {    
    PairOfNumbers numbers1 = new PairOfNumbers();            
    PairOfNumbers numbers2 = new PairOfNumbers();        
    SumObserver sum = new SumObserver(numbers1);        
    ProductObserver prod = new ProductObserver(numbers2);    
    MultiSubjectObserver m = new MultiSubjectObserver();
    m.addSubject(numbers1);
    m.addSubject(numbers2);        
    numbers1.setNumbers(20, 10);
    numbers2.setNumbers(-10, 15);       
}    


class Subject {
    private List<Observer> observers=new ArrayList<Observer>();
    public void attachObserver(Observer observer) {
    this.observers.add(observer);
    }
    public void detachObserver(Observer observer) {
        this.observers.remove(observer);
    }
    public void notifyObservers() {
    for (Observer observer: this.observers)
        observer.update(this);
    }
}   

class PairOfNumbers extends Subject {
    private double number1, number2;
    public double getNumber1() { return this.number1; }
    public double getNumber2() { return this.number2; }
    public void setNumbers(double d1, double d2) {
    this.number1=d1; this.number2=d2;
    this.notifyObservers();  // don't forget to do this!
    }
} 

abstract class Observer {
    public Observer(Subject subject) {
    subject.attachObserver(this);
}

abstract public void update(Subject subject);
}

class SumObserver extends Observer {
    public SumObserver(PairOfNumbers pair) {
    super(pair);
    }
    public void update(Subject subject) {
    PairOfNumbers numbers=(PairOfNumbers)subject;
    System.out.println("New sum is: "+(numbers.getNumber1()+numbers.getNumber2()));
    }
}

class ProductObserver extends Observer {
    public ProductObserver(PairOfNumbers pair) {
        super(pair);        
    }
    public void update(Subject subject) {
   PairOfNumbers numbers=(PairOfNumbers)subject;
   System.out.println("New product is: "+(numbers.getNumber1()*numbers.getNumber2()));
    }
}

好的,现在我想创建另一个继承上述类的类。

class MultiSubjectObserver extends Observer{
    public MultiSubjectObserver(PairOfNumbers pair){
        super(pair);
    }   

    public void addSubject(PairOfNumbers pair){
        pair.attachObserver(this);
    }

    public void update(Subject subject){
        PairOfNumbers numbers=(PairOfNumbers)subject;
        System.out.println("MultiSubjectObserver activated with numbers: " +    (numbers.getNumber1())+", "+(numbers.getNumber2()));
    }        
}

有没有办法在MSO类中创建一个不需要参数/参数的构造函数?例如

public MultiSubjectObserver(){
    //enter code here 
}

请指导我这个。好几天都在想。提前致谢! :d

指令是:修改源代码以处理每个观察者的任意数量的主题对象。

预期输出:

New sum is: 30.0 
MultiSubjectObserver activated with numbers: 20.0, 10.0 
New product is: -150.0 
MultiSubjectObserver activated with numbers: -10.0, 15.0

1 个答案:

答案 0 :(得分:0)

是的,你可以这样做,创建一个无参数的子类,但是你仍然必须在子构造函数中调用需要arg的超级构造函数。

此:

class Child extends Super {
   public Child() {
      super(args_are_needed);
   }
}

棘手的部分是 - 在这个默认情况下传递给超级构造函数的内容是什么?在您的情况下,可以

public MultiSubjectObserver(){
    super(null);
}

警告:,当调用超级构造函数时,由于行subject.attachObserver(this);,这将导致NullPointerException,所以不,你不能这样做。

更好的解决方案:确保MultiSubjectObserver从Observer扩展 而不是

也许是这样的:

class MultiSubjectObserver {
   private List<Observer> observerList = new ArrayList<Observer>();

   public void addSubject(PairOfNumbers numbers1) {
      observerList.add(new InnerObserver(numbers1));
   }

   private class InnerObserver extends Observer {
      public InnerObserver(Subject subject) {
         super(subject);
      }

      @Override
      public void update(Subject subject) {
         System.out.println("From multi-observer: " + subject);
      }
   }    
}

但要实现这一点,你必须给PairOfNumbers一个像样的toString方法,或许,

@Override
public String toString() {
   return String.format("[%.4f, %.4f]", number1, number2);
}

修改
根据输出结果:

class MultiSubjectObserver {
   private static final String FORMAT_STRING = "MultiSubjectObserver activated with numbers: %.1f, %.1f%n";
   private List<Observer> observerList = new ArrayList<Observer>();

   public void addSubject(PairOfNumbers numbers1) {
      observerList.add(new InnerObserver(numbers1));
   }

   private class InnerObserver extends Observer {
      public InnerObserver(Subject subject) {
         super(subject);
      }

      @Override
      public void update(Subject subject) {
         System.out.printf(FORMAT_STRING, ((PairOfNumbers)subject).getNumber1(),  ((PairOfNumbers)subject).getNumber1());
      }
   }
}

虽然那个演员有点邋..我更喜欢toString()版本更多