2014-09-28 7 views
0

나는이 과제를 고수하고있다. 나는 오직 하나의 생성자, 파라미터/인자를 가진 생성자를 가진 추상 Observer 클래스를 받았다. (아래 참조)옵저버 패턴 클래스 (JAVA)

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

지침은 다음과 같습니다. Observer 당 여러 개의 Subject 객체를 처리하도록 소스 코드를 수정합니다.

예상 출력 :

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

예를 들어, 'Observer'에게 인수가없는 생성자를 제공하면 그렇습니다. – immibis

+0

@immibis : 절대적으로 필요하지 않음 –

답변

0

예이 작업을 수행 할 수는 인수 없음의 하위 클래스를 만들 수 있지만 여전히 자식 생성자 내에서 인수-필요 슈퍼 생성자를 호출해야합니다.

이 :

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

까다로운 부분이 될 것이다 -이 기본 경우에 슈퍼 생성자에 무엇을 전달하려면? 귀하의 경우에는이 수 :

public MultiSubjectObserver(){ 
    super(null); 
} 

경고 :는이 슈퍼의 생성자 인해 라인, subject.attachObserver(this);에,라고는 NullPointerException으로 이어질 것입니다, 그래서 아니,이 작업을 수행 할 수 없습니다 .

더 나은 솔루션 : MultiSubjectObserver이하는 사항을 반드시 준수 하지 관찰자에서 연장!

아마도 같은 :

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() 버전이 이 훨씬 더 많다.이 더 좋다.

+0

OMG! 고마워요! 나의 날을 구했다! :) – NewbieCoder

+1

@ user3774597 : 내 대답의 맨 아래에주의하십시오. 왜 당신은 자식 클래스를위한 인자없는 생성자가 필요하다고 생각하니? –

+0

Ouwh, 그건 내 Main 메서드에서, 주어진 생성자가'MultiSubjectObserver m = new MultiSubjectObserver();'이고 나는 그것을 변경할 수 없다. – NewbieCoder