Я считаю, что у меня вопрос дизайна, и я надеюсь получить ваш вход. Я сделал небольшую программу, чтобы проиллюстрировать мой вопрос. В принципе, моя программа состоит из радиосистемы, которая слышится в каждой комнате здания. Звук зависит от принимающего конца, в зависимости от того, входит ли камера в радиосистему.Conditional EventHandling
Проблема заключается в том, что отправленное сообщение запускается в каждой комнате, даже если номер не зарегистрирован. Я бы предпочел выполнить условие до того, как сообщение будет отправлено, а не на принимающей стороне. Делая это, я мог бы сэкономить ненужный трафик. Может ли кто-нибудь дать мне идею или правильный способ решить эту ситуацию?
Как раз для записи, я бы предпочел не иметь в радио нескольких обработчиков событий, так как я не знаю, сколько комнат будет.
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();
}
}
}
У вас есть некоторые проблемы с основным дизайном для разработки. Во-первых, ваше радио не должно знать о конкретных комнатах. Радио должно быть в состоянии нормально работать * независимо от того, в какую комнату вы его положили *. Конечно, как вы должны это делать правильно, зависит от ваших фактических требований, и мы не знаем, каковы ваши требования. – Servy
radioPlayer.onRadio + = radioPlayer_onRadio; это в основном регистрация для радио звука. Не регистрируйтесь, если вы не хотите слышать радио. Механизм обработки событий - это, в основном, потребительский шаблон производителя событий. –
Я ищу, чтобы в комнате N слушали только сообщения, предназначенные для его комнаты. Мой способ разрешить это - сделать условие на принимающей стороне. Все номера должны регистрироваться, но я хочу избежать ненужного трафика. – MIJ1974