C#策略和观察者模式代码

时间:2013-05-07 12:57:07

标签: c# observer-pattern strategy-pattern

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

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

   } 

 }

2 个答案:

答案 0 :(得分: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);

    }

答案 1 :(得分: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);
 }