0

您好我正在尝试创建抽象类 Person 和两个子类 Student 和 Staff。Person 类也有一个由 Practical 类通知的观察者。但学生只会收到有关更改的问题编号和有关学生感觉良好因素的工作人员的通知。任何学生都可以随时标记该因素。我已经设法让观察者工作,但仅限于 Person 类。我知道我必须将其抽象化,然后创建 Staff 和 Student 类,但我无法理解它。任何帮助都会很棒。谢谢 这是代码:

namespace ConsoleApplication1
{
class Practical : IPractical    //Practical class
{
    private String QuestionNumber;// the state which observers are interested in.
    private String Factor;
    private ArrayList observers;    // the collection of observers attached to this subject.

    public Practical(String qnumber, String f)
    {
        QuestionNumber = qnumber;
        Factor = f;
        observers = new ArrayList();
    }

    public void AddObserver(IPerson o) { observers.Add(o); }
    public void RemoveObserver(IPerson o) { observers.Remove(o); }

    public void NotifyObserverQN()
    {
        foreach (IPerson o in observers) { o.Update(QuestionNumber); }
    }

    public void NotifyObserverFactor()
    {
        foreach (IPerson o in observers) { o.Update(Factor); }
    }

    public String QN
    {
        get { return QuestionNumber; }
        set
        {
            QuestionNumber = value;
            NotifyObserverQN();     //notify about new question
        }
    }

    public String Fc
    {
        get { return Factor; }
        set
        {
            Factor = value;
            NotifyObserverFactor();     //notify about new ffctor
        }
    }
   }

      interface IPractical  //IPractical interface
     {
           void AddObserver(IPerson o);
           void RemoveObserver(IPerson o);
           void NotifyObserverQN();
           void NotifyObserverFactor();
    }



  class Person : IPerson
   {

    private string id;
    public Person(string i) { id = i; }
    public void Update(Object o)     { Console.WriteLine(" {0} notified about {1} .", id, o.ToString()); }

}

  interface IPerson     //Observer interface
   {
      void Update(Object o);

    }



 class Observer
  {

    public static void Main()
    {
        Console.WriteLine("\n\nStart\n\n");
        Practical practical = new Practical("Question", "Factor");
        IPerson a, b, c;
        a = new Person(" Student_1 ");
        b = new Person(" Student_2 ");
        c = new Person(" Staff_1   ");

        practical.AddObserver(a);
        practical.AddObserver(b);
        practical.AddObserver(c);

        practical.QN = "Question 1";   // all students notifie about Question 1 
        practical.Fc = "Feel-Good";
        practical.QN = "Question 2";   // all students notifie about Question 2
        practical.Fc = "Feel-Bad";

        Console.WriteLine("\n\nEnd\n\n");
    }

   } 

 }
4

2 回答 2

0

理想情况下,您需要一个显式强制转换来检查特定观察者的类型是 Student 还是 Staff。在这种情况下,您可以将通知方法概括如下,而不是编写两个通知方法。

    public void Notify()
    {
        foreach (IPerson o in observers)
        {
            if (IPerson is Student)
                o.Update(QuestionNumber);// Student - question number 
            else
                o.Update(Factor);//Staff -  feel-good factor

        }
    }

根据关于在这种情况下继承如何工作的请求;

 public abstract class Person : IPerson
    {
        private string id;
        public Person(){}
        public Person(string i)
        {
            id = i;
        }
        public abstract void Update(Object o);
    }
    public class Student:Person
{
    public Student(){}
    public Student(string i):base(i)
    {
    }
    public override void Update(object o)
    {
        //whatever you wanted to do with Student
    }
}
public class Staff : Person
{
     public Staff(){}
     public Staff(string i)
         : base(i)
    {
    }
    public override void Update(object o)
    {
        //whatever you wanted to do with Staff
    }
}    
    interface IPerson     //Observer interface
    {
        void Update(Object o);

    }
于 2013-05-07T13:07:44.213 回答
0

我想在 C# 中补充一点,我更喜欢通过事件来实现观察者。观察者不必知道谁在观察它们以及它们的类型,而是在被观察类中引发事件。在您的情况下,您将在 Practical 类中引发 QuestionChanged 和 FactorChanged 事件。当你创建你的观察者时,你将他们注册到你的员工和学生班级,他们会选择他们感兴趣的事件。这样,没有人需要知道另一个是什么类型。

像这样的东西(伪代码,可能无法编译):

public class Practical {
    ...
public event EventHandler QNChanged;
public event EventHandler FcChanged;
public String QN
{
    get { return QuestionNumber; }
    set
    {
        QuestionNumber = value;
        OnQNChanged();     //notify about new question
    }
}

public String Fc
{
    get { return Factor; }
    set
    {
        Factor = value;
        OnFcChanged();     //notify about new ffctor
    }
}

protected void OnFcChanged(){
    if(this.FcChanged != null) {
         FcChanged(this, null);
    }
}

protected void OnQnChanged(){
    if(this.QnChanged != null) {
         QnChanged(this, null);
    }
}
...
}

public class Student {
     public Student(Practical practical){
          practical.QnChanged += Update;
     }

     public void Update(object sender, EventArgs args){
          Practical practical = (Practical) sender;
          // do something with practical
     }
}

public class Staff{
     public Staff(Practical practical){
          practical.FnChanged += Update;
     }

     public void Update(object sender, EventArgs args){
          Practical practical = (Practical) sender;
          // do something with practical
     }
}

class Observer
{

public static void Main()
{
    ....
    var practical = new Practical("Question", "Factor");

    var a = new Student(practical);
    var b = new Staff(practical);

    practical.QN = "Question 1";   // all students notified about Question 1 
    practical.Fc = "Feel-Good";
    practical.QN = "Question 2";   // all students notified about Question 2
    practical.Fc = "Feel-Bad";
    ....

  }

 } 

注意:你不必在构造函数中包含被观察项,你也可以添加一个方法来注册它,如果你愿意,它只是让例子更简单。即,您的教职员工和学生可以实现此接口:

 public interface IPracticalObserver {
      void RegisterPractical(IPractical practical);
      void Update(object practical, EventArgs args);
 }
于 2013-05-07T14:40:13.787 回答