C # - Особенности дизайна событий - PullRequest
3 голосов
/ 26 ноября 2009

Мне нужна система уведомления о событиях, которая должна уведомлять врача, когда сердцебиение пациента превышает 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 ]

3 голосов
/ 26 ноября 2009

Ну, во-первых, я обычно думаю, что это плохая идея слушать события класса в том же классе, если у вас есть доступ к нему.

Это также хорошая идея получить из EventArgs, который рекомендован MS.

Ответственность за возникновение события действительно должна лежать на самом классе пациента, но здесь вы поднимаете только событие класса, в котором вы вызываете саму функцию 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;
        }
    }
2 голосов
/ 26 ноября 2009

Метод OnAbnormalPulseRaised (Patient p) следует поместить в класс «Доктор», потому что именно доктор получает уведомление о событии. Свойство события должно быть помещено в класс Patient, потому что пациенты вызывают события:

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

Издатель - это объект со свойством события. Подписчик - это объект с методом-обработчиком.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...