Search code examples
c#observer-patternstrategy-pattern

C# strategy and observer pattern code


Hi I'm trying to create abstract class Person and two child classes Student and Staff. Person class also has an observer that is notified by a Practical class. But Students will be notified only about question number changed and Staff about student's feel-good factor. That factor can be marked at any time by any student. I've managed to get observer working but only with Person class. I know I hav to make it abstract and then create Staff and Student classes but I just can't get my head round it. Any help would be great. Thanks Here s the code:

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

   } 

 }

Solution

  • Ideally, you need an explicit casting which check a particular observer is of type Student or Staff. In such case, you can generalize your notification method as below instead of writing two notification methods.

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

    As per the request on how inheritance works in this case;

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