領域驅動設計系列 (四):事件驅動下


前言

上一篇說到為什么要使用事件驅動,但是只有概念是不夠的,我們要代碼呀!記得臉書的老總說過: "Talk is cheap, Show me the code!"

實現思路

發出事件

事件顧名思義就是一件事情發生了,比如我要上頭條,這不是一個事件,這事一個Command, HeadCommand, 而我上頭條了這就是一個事件HeadedEvent,事件就是一件事情已經發生了。 好,先來一個偽代碼

   public void Head()
    {
        var NewsPaper = new NewsPaper("南都娛樂");
        NewsPaper.WriteToHeader("汪峰");

        RaiseEvent(new HeadedEvent {Name = "汪峰"});
    }

所以我們只需在代碼里RaiseEvent就可以了。

那么如何訂閱事件

其實很簡單,因為我們要實現的是同步的事件,我們只需要找到所有處理這個事件的實現類,然后調用所有就可以了。

public interface IEventHandler<TEvent> where TEvent : Event
{
    void Handle(TEvent e);
}

public class HeadedEvent:Event
{
    public string Name { get; set; }
}

如果國際章的媽媽關注這個Event, 我們就實現一個GuoJiZhangMotherEventHandler

public class GuoJiZhangMotherEventHandler : IEventHandler<HeadedEvent>
{
    public void Handle(HeadedEvent e)
    {
         Console.WriteLine(e.Name+", Are you kidding me?");
    }
}

如果我等屁民也關心這個事件的話,我們只需要再實現一個 PiMingEventHandler

public class PiMingEventHandler:IEventHandler<HeadedEvent>
{
    public void Handle(HeadedEvent e)
    {
        Console.WriteLine(e.Name+", Guo Ji Zhang is your last wife?");
    }
}

看,我們可以任意增加關注事件的代碼,不用修改原來的代碼吧,說好的OCP沒騙你吧? 那么問題來了,發出事件的人和接受事件的人怎么聯系上的?在現實世界中,我們都是訂閱報紙來看頭條知道的,但是代碼里我們就需要一個協調者了。如是我們就需要一個EventBus, 直接上代碼吧

    public void Head()
    {
        var NewsPaper = new NewsPaper("南都娛樂");
        NewsPaper.WriteToHeader("汪峰");

        RaiseEvent(new HeadedEvent {Name = "汪峰"});
    }

    private void RaiseEvent(HeadedEvent headedEvent)
    {
        EventBus.Publish<HeadedEvent>(new HeadedEvent { Name = "汪峰" });
    }

EventBus找出所有Handle這個事件的實現類,調用對應的Handle方法,我們可以通過Castle或者任何注入框架輕易的實現

public class EventBus
{
    public static void Publish<T>(T concreteEvent) where T: Event
    {
        var handlers = _container.ResolveAll<IEventHandler<T>>();
        foreach (var handle in handlers)
        {
            handle.Handle(concreteEvent);
        }
    }
}

好了,哥只負責幫汪老師上頭條,上完我發出了事件通知,誰關注誰自己處理去,我的代碼也不用改。

我代碼實現完了,如果各位還不知道如何實現一個同步的事件驅動架構,那拜托你們找個漂亮的妹子來問我。事件驅動架構我就只能幫你到這里了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM