C# - 事件设计注意事项

时间:2009-11-26 07:14:59

标签: c# events

我想要一个事件通知系统,当患者的心跳大于120时,应该通知医生。我不知道,如何设计这样的系统。我刚刚实施了错误的一个。帮助我实现正确的。

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

除此之外,我希望得到一个共同的澄清。

记住发布者和观察者模式的最佳方法是什么?因为我很难混淆在哪里实施发布者以及在哪里实施

2 个答案:

答案 0 :(得分:3)

嗯,对于初学者来说,如果你有权访问同一个班级,我通常认为听一个班级的事件是一个坏主意。

从MS推荐的EventArgs派生出来也是一个好主意。

提升事件的责任应该确实在患者类本身,但是在这里你只引发你调用HardBeatSimulation函数的类的事件,而不是实际上有异常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;
        }
    }

答案 1 :(得分:2)

OnAbnormalPulseRaised(患者p)的方法应该放在Doctor类中,因为医生是被通知事件的人。事件属性应该放在患者类中,因为患者正在提高事件:

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是具有event属性的对象。订阅者是具有处理程序方法的对象。