tags:

views:

113

answers:

2

I want an event notification system that should notify the doctor when the heartbeat of the patient is greater than 120.I do not know, How to design such system. Just I have implemented the wrong one. Help me in implementing the correct one.

     static void Main()
    {
     Patient[] patList = { new Patient 
     { PatientID = "1", HeartBeat = 100 },
       new Patient { PatientID = "2", HeartBeat = 130 } };

        List<Patient> plist = patList.ToList();
        Console.ReadKey(true);
    }


public  class Doctor
    {
        public event PulseNotifier AbnormalPulseRaised;
        public string Name
        {
            get;
            set;
        }
    }



public   class Patient
    {
        public event PulseNotifier AbnormalPulseRaised;
        static Random rnd = new Random(); 

        public Patient()
        {
            PulseNotifier += new PulseNotifier(OnAbnormalPulseRaised);
        }
        public string PatientID
        {
            get;
            set;
        }

        public int HeartBeat
        {
            get;
            set;
        }

        public void HeartBeatSimulation(List<Patient> patList)
        {
            foreach(Patient p in patList)
            {
                if (p.HeartBeat > 120)
                {
                    if (AbnormalPulseRaised != null)
                    {
                        AbnormalPulseRaised(p);
                    }
                }
            }
        }

        public void OnAbnormalPulseRaised(Patient p)
        {
            Console.WriteLine("Patient Id :{0},Heart beat {1}",
            p.PatientID, p.HeartBeat);
        }
    }

Apart from that, I want to have a common clarification.

What is the best way to remember the publisher and observer pattern?. Because I am quite confusing about where to implement publisher and where to implement

+2  A: 

The method OnAbnormalPulseRaised(Patient p) should be placed in Doctor class because doctor is the one being notified about event. The event property should by placed in Patient class because patients are raising the events:

public  class Doctor
{
        public Doctor()
        {
            // doctor initialization - iterate through all patients
            foreach(patient in patList) 
            {
                 // for each patient register local method as event handler
                 // of the AbnormalPulseRaised event.
                 patient.AbnormalPulseRaised += 
                    new PulseNotifier(this.OnAbnormalPulseRaised);

            }
        }

        public void OnAbnormalPulseRaised(Patient p)
        {
            Console.WriteLine("Patient Id :{0},Heart beat {1}",
            p.PatientID, p.HeartBeat);
        }


        public string Name
        {
            get;
            set;
        }
}

public   class Patient
{
        public event PulseNotifier AbnormalPulseRaised;
        static Random rnd = new Random(); 

        public Patient()
        {
        }

        public string PatientID
        {
            get;
            set;
        }

        public int HeartBeat
        {
            get;
            set;
        }

        public void HeartBeatSimulation(List<Patient> patList)
        {
            foreach(Patient p in patList)
            {
                if (p.HeartBeat > 120)
                {
                    if (AbnormalPulseRaised != null)
                    {
                        AbnormalPulseRaised(p);
                    }
                }
            }
         }
    }

Publisher is the object with event property. Subscriber is the object with handler method.

PanJanek
+2  A: 

Well, for starters, I usually think it's an bad Idea to listen to the events of a class in the same class if you have access to it.

It's also a good idea to derive from EventArgs, which is recommended by MS.

The responsibility of raising the event should indeed be in the patient class itself, but here you raise only the event of the class where you call the HardBeatSimulation function itself instead of on the patient that actually has an abnormal pusle :)

    static void Main(string[] args) {
        Patient pat1 = new Patient(1, 120);
        Patient pat2 = new Patient(3, 150); // this one can have a 150 bpm hartbeat :)
        Doctor fancyDoctor = new Doctor();
        fancyDoctor.AddPatient(pat1);
        fancyDoctor.AddPatient(pat2);
        Console.ReadKey(true);

    }

    public class Doctor {
        List<Patient> _patients;
        public event EventHandler Working;


        public Doctor() {
            _patients = new List<Patient>();
        }

        public void AddPatient(Patient p) {
            _patients.Add(p);
            p.AbnormalPulses += new EventHandler<AbnormalPulseEventArgs>(p_AbnormalPulses);
        }

        void p_AbnormalPulses(object sender, AbnormalPulseEventArgs e) {
            OnWorking();
            Console.WriteLine("Doctor: Oops, a patient has some strange pulse, giving some valium...");
        }

        protected virtual void OnWorking() {
            if (Working != null) {
                Working(this, EventArgs.Empty);
            }
        }

        public void RemovePatient(Patient p) {
            _patients.Remove(p);
            p.AbnormalPulses -= new EventHandler<AbnormalPulseEventArgs>(p_AbnormalPulses);
        }
    }

    public class Patient {
        public event EventHandler<AbnormalPulseEventArgs> AbnormalPulses;

        static Random rnd = new Random();
        System.Threading.Timer _puseTmr;
        int _hartBeat;

        public int HartBeat {
            get { return _hartBeat; }
            set {
                _hartBeat = value;
                if (_hartBeat > MaxHartBeat) {
                    OnAbnormalPulses(_hartBeat);
                }
            }
        }

        protected virtual void OnAbnormalPulses(int _hartBeat) {
            Console.WriteLine(string.Format("Abnormal pulsecount ({0}) for patient {1}", _hartBeat, PatientID));
            if (AbnormalPulses != null) {
                AbnormalPulses(this, new AbnormalPulseEventArgs(_hartBeat));
            }
        }

        public Patient(int patientId, int maxHartBeat) {
            PatientID = patientId;
            MaxHartBeat = maxHartBeat;
            _puseTmr = new System.Threading.Timer(_puseTmr_Tick);

            _puseTmr.Change(0, 1000);
        }

        void _puseTmr_Tick(object state) {
            HartBeat = rnd.Next(30, 230);
        }

        public int PatientID {
            get;
            set;
        }

        public int MaxHartBeat {
            get;
            set;
        }
    }

    public class AbnormalPulseEventArgs : EventArgs {
        public int Pulses { get; private set; }
        public AbnormalPulseEventArgs(int pulses) {
            Pulses = pulses;
        }
    }
Stormenet
@Stormenet No event is raised .
Didn't test the code, will try it out in a minute :)
Stormenet
Okay, it works now, Needed to use the System.Threading.Timer instead of System.Windows.Forms.Timer since there isn't an application loop :)
Stormenet