mardi 26 mai 2015

Conditional EventHandling

I believe I have a design question and I hope to get your input. I made a small program to illustrate my question. Basically, my program consists of a radio system that gets heard on every room in the building. The sound is conditional on the receiving end, depending if the room registers itself to the radio system.

My problem is that the message sent is triggered on every room, even if the room is not registered. I would prefer to do the condition before the message gets sent out, rather then on the receiving end. By doing this, I could save myself unnecessary traffic. Can anyone give me an idea or the correct way to resolve this type of situation?

Just for the record, I would prefer not to have multiple event handlers in the radio, since I don't know how many rooms there will be.

Thank you so much.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Radio
{
#region Speakers
public interface ISound
{
    string sound { get; set; }
}
public abstract class RoomSpeaker : ISound
{
    public string sound { get; set; }
}
public class Room1Speaker : RoomSpeaker
{
}
public class Room2Speaker : RoomSpeaker
{
}
public class BuildingSpeaker : RoomSpeaker
{
}
#endregion
#region Rooms
public abstract class Room
{
    public Radio radioPlayer;
    public string name;
    public HashSet<Type> registeredSpeakers = new HashSet<Type>();

    public virtual void RoomPlayer(string lyrics)
    {
        registeredSpeakers.Add(typeof(BuildingSpeaker));
        Console.WriteLine(lyrics);
    }
}
public class Room1 : Room
{
    public Room1(Radio radioPlayer)
    {
        this.radioPlayer = radioPlayer;
        name = "Room1";
        registeredSpeakers.Add(typeof(Room1Speaker));
        radioPlayer.onRadio += radioPlayer_onRadio;
    }

    // This is what I don't think I like.  It will only do something if it's registered. That's fine.
    // But on any radio message out, this room will get called regardless.  Should I NOT be doing this? Should I go back to
    // making an eventHandler for every room? rather then having one even handler for all the rooms and have a condition on the receiving end.

    void radioPlayer_onRadio(object sender, ISound e)
    {
        if (registeredSpeakers.Contains(e.GetType()))
            RoomPlayer(name + e.sound);
    }
}
public class Room2 : Room
{
    public Room2(Radio radioPlayer)
    {
        this.radioPlayer = radioPlayer;
        name = "Room2";
        registeredSpeakers.Add(typeof(Room2Speaker));
        radioPlayer.onRadio += radioPlayer_onRadio;
    }

    void radioPlayer_onRadio(object sender, ISound e)
    {
        // same problem as in Room1. 
        if (registeredSpeakers.Contains(e.GetType()))
            RoomPlayer(name + e.sound);
    }
}
#endregion

public class Radio
{
    public event EventHandler<ISound> onRadio;

    public void PlayRoom1()
    {
        onRadio(this, new Room1Speaker() { sound = "Test" });
    }
    public void PlayRoom2()
    {
        onRadio(this, new Room2Speaker() { sound = "Test" });
    }
    public void PlayAllRooms()
    {
        onRadio(this, new BuildingSpeaker() { sound = "Test All Rooms" });
    }
}

class Program
{
    static void Main(string[] args)
    {
        var radio = new Radio();
        var room1 = new Room1(radio);
        var room2 = new Room2(radio);

        radio.PlayRoom1();
        radio.PlayRoom2();
        radio.PlayAllRooms();
        Console.ReadLine();
    }
}

}

Aucun commentaire:

Enregistrer un commentaire