В соответствии с более ранним вопросом, я сказал пользователю, что я не должен выставлять API-интерфейс.NET Event-style, если только не будет принудительно:
Если вы не будете вынуждены сделать это, не делайте API с использованием событий стиля С#.
В этом случае, как мне реализовать "событие", когда модель будет уведомлять наблюдателей о том, что она каким-то образом изменилась? Событие ожидается только один раз. Скажем, например, что моя модель представляет собой блок Minecraft, и я вызываю метод Destroy()
на этой модели. Метод Destroy()
должен передавать наблюдателям, что эта модель намеревается уничтожить. Например, наблюдатели будут контроллером, который затем отправит уведомление BlockDestroyed
в представление (я считаю, что контроллер может быть ненужным уровнем косвенности, но гораздо проще сделать модель → контроллер → просмотр, а не модель (наблюдаемая) - > view (observer)).
Вот мой код, который я бы хотел изменить в стиле Rx - помните, что Destroyed
будет вызываться только один раз за блок - и могут быть другие события, такие как Damaged
, Activated
и TextureChanged
.
public class Block
{
public Block()
{
}
/// <summary>
/// Destroy the block.
/// </summary>
public void Destroy()
{
var msg = new BlockDestroyedMessage();
if (Destroyed != null)
Destroyed(this, msg);
}
public event EventHandler<BlockDestroyedMessage> Destroyed;
}
Также обратите внимание, что я вижу документацию по сети, которая в основном вы
ISubject<T>
поскольку он поощряет нарушение SRP (с которым я согласен)IObservable<T>
(потому что существует так много заводских методов для создания наблюдаемых)Я бы сделал это:
public class Block
{
public void Destroy()
{
if (_destroyed != null)
{
var msg = new BlockDestroyedMessage();
_destroyed.OnNext(msg);
_destroyed.OnCompleted();
_destroyed = null;
}
}
private Subject<BlockDestroyedMessage> _destroyed
= new Subject<BlockDestroyedMessage>();
public readonly IObservable<BlockDestroyedMessage> Destroyed
= _destroyed.AsObservable();
}
IObservable
как свойство только для чтения, а не как изменяемое поле.