領域驅動設計系列(三):事件驅動上


前言

今天講一下事件驅動,這個不是領域驅動設計里的事件源(Event Source), 這個以后再講,今天主要講一下如何用事件來解耦,主要的原因是我們有個項目有個功能我覺得用事件的方式比較好,正好寫篇博客,就不用專門給他們講了。

解耦

說到解耦,我們很熟悉分層設計,比如上層依賴於抽象,不依賴於具體的實現。比如一個類使用另一個類,我們使用接口而不直接使用實現類。

 public EquipmentService(IEmailService emailService, IEquipmentRepository equipmentRepository)
    {
        _emailService = emailService;
        _equipmentRepository = equipmentRepository;
    }

為何用事件?

SRP (單一職責)

比如我們一個會議室預定系統,我們的一個設備壞了。我們需要通知預定這個會議室的所有人。於是我們需要發郵件。

偽代碼如下

public class EquipmentService
{
    private readonly IEmailService _emailService;
    private readonly IEquipmentRepository _equipmentRepository;

    public EquipmentService(IEmailService emailService, IEquipmentRepository equipmentRepository)
    {
        _emailService = emailService;
        _equipmentRepository = equipmentRepository;
    }

    public void SetEquipmentBroken(string Id)
    {
        var equipment = _equipmentRepository.GetById(Id);
        equipment.DeActive();

        _emailService.SendEmail();
    }
}

但是,問題來了,如果后來我們要說,如果設備壞了,我們要更改可用庫存的數量,這時候我們是不是要在這里修改代碼而引入IInventoryService? 后來如果經理說設備壞了你們盡然不告訴我,你們要鬧哪樣?這個時候我們是不是要修改代碼引入ISMSService.Info(Manager)? 即使我們不考慮OCP原則,不考慮單一職責,我們程序員也會哭,我就DeActive一個設備,你要我做這么多事,我哪里清楚所有的功能?我就罵過程序員,你做這個功能呢為什么沒考慮全!!!漏掉了這么重要的功能。

而問題,程序員從來沒考慮全過,因此我就想辦法如何解決這個程序員不仔細的問題。

事件驅動

因為我熟悉iOS的開發,我就想到了iOS的Notification Center. 那我我DeActive一個設備,我就只DeActive這個設備,很SRP是不是? 但是別的地方如何拿到通知? 於是事件就自然的付出水面了。如果設備被DeActive了,程序就只需要喊一聲,老子把設備DeActive了,你們要鬧哪樣你們自己看着辦,代碼如下。

 public void SetEquipmentBroken(string Id)
    {
        var equipment = _equipmentRepository.GetById(Id);
        equipment.DeActive();

        EventBus.Publish(new EquipmentDeActivedEvent {Id = equipment.Id});

    }

這樣,通知會議室預定者的模塊去通知,給老板發短信的模塊就通知老板就OK了。

總結

這里我們先將事件驅動,下一篇展示如何實現同步的事件,以后轉換為異步那也很容易,讓多個接受者處理這個事件,接受者可以是動態的哦,以后老板娘也想知道的話,代碼也不用改的親,好,我先去寫實現代碼去!


免責聲明!

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



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