简体   繁体   English

观察者模式类(JAVA)

[英]Observer Pattern Class (JAVA)

I'm stuck on this assignment. 我被这项任务卡住了。 I'm given an abstract Observer class with only 1 constructor in it, a constructor with parameters/arguments. 我给了一个抽象的Observer类,其中只有1个构造函数,一个带有参数/参数的构造函数。 (refer below) (请参阅下文)

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

Okay, now I'm suppose to create another class which inherits from the above class. 好的,现在我想创建另一个继承自上述类的类。

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

Is there a way to create a constructor inside the MSO Class which requires no parameter/argument? 有没有一种方法可以在MSO类中创建不需要参数/参数的构造函数? For example 例如

public MultiSubjectObserver(){
    //enter code here 
}

Please guide me on this one. 请指导我这一件事。 Had been thinking for days. 想了好几天。 Thanks in advance! 提前致谢! :D :D

The instruction is to: Modify the source code to handle any number of Subject objects per Observer. 该指令用于:修改源代码以处理每个观察者任意数量的Subject对象。

Expected output: 预期产量:

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

Yes you can do this, create a no-arg child class, but you still must call the arg-needing super constructor within the child constructor. 是的,您可以执行此操作,创建一个无参数的子类,但仍必须在子构造函数中调用需要arg的超级构造函数。

This: 这个:

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

The tricky part would be -- what to pass into the super constructor in this default case? 棘手的部分是-在这种默认情况下,什么要传递给超级构造函数? In your case this could be: 在您的情况下, 可能是:

public MultiSubjectObserver(){
    super(null);
}

Caveat: and this will lead to a NullPointerException when the super's constructor is called, due to the line, subject.attachObserver(this); 警告:这将导致在调用super的构造函数时导致NullPointerException,这是因为该行是subject.attachObserver(this); , so no, you can't do this. ,所以不行,您不能这样做。

A better solution: make sure that MultiSubjectObserver does not extend from Observer! 更好的解决方案:确保MultiSubjectObserver 从观察者延伸!

Perhaps something like: 也许像这样:

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

But for this to work, you'd have to give PairOfNumbers a decent toString method, perhaps, 但是要使其正常工作,您必须给PairOfNumbers一个不错的toString方法,也许,

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

Edit 编辑
Based on the output: 根据输出:

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

Although that casting is a bit skanky. 虽然那种铸造有点卑鄙。 I like the toString() version much better. 我喜欢的toString()版的好得多。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM