簡體   English   中英

活動訂閱最佳做法

[英]Event subscription best practices

我最近在我們的應用程序中偶然發現了以下內容,並且很好奇這是好還是壞的做法。 我看到的是事件在應用程序,業務邏輯以及最終在我們的框架中的不同級別上被訂閱。

我們具有對用戶進行身份驗證和授權的功能,該功能由HttpModule精心安排,該模塊基本上執行以下操作(我僅包括最相關的部分):

    public class FooModule : IHttpModule
    {
        private IIdentityProvider _identityProvider;

        public void Init(HttpApplication context)
        {
            _identityProvider = TypeFactory.Create<IIdentityProvider>("...type string from configuration...");
            identityProvider.Init(context, ...);

            context.PostAuthenticateRequest += OnAuthenticateRequest;
            context.PostAuthenticateRequest += OnAuthenticateRequestLogging;
        }

        ...
    }

到目前為止,一切都很好:HttpModule標識已配置的身份提供程序,對其進行初始化並預訂一些事件。 事件處理程序在這里不是問題,因此我省略了它們。

然后,在初始化任意身份提供者時:

public class BarIdentityProvider : IIdentityProvider
{
    public void Init(HttpApplication httpApplication, ...)
    {
        var authorizer = new BarAuthorizationProvider();
        authorizer.Init(httpApplication, ...);

        httpApplication.PostAuthenticateRequest += httpApplication_PostAuthenticateRequest;
        httpApplication.AuthorizeRequest += httpApplication_AuthorizeRequest;
    }

    ...
}

在AuthorizationRequestHandler中發生以下情況:

public class BarAuthorizationProvider
{
    public void Init(HttpApplication httpApplication, ...)
    {
        httpApplication.PostAuthorizeRequest += OnAuthorizeRequest;
    }

    ...
}

如您所見,在FooModule,BarIdentityProvider和BarAuthorizationProvider中已訂閱了事件,對我而言,它們是事件面條。 另外,在執行此操作時:

var authorizer = new BarAuthorizationProvider();
authorizer.Init(httpApplication, ...);

我不希望authorizer者訂閱各種事件並“神奇地”工作。

作為軟件開發人員,我期望:

  1. 一個HttpModule,它訂閱必要的事件並向身份提供者和授權提供者請求身份和訪問信息。 提供程序中的事件處理被最小化。
  2. 多個HttpModule(即身份驗證和授權模塊),每個模塊都訂閱必要的事件。 提供程序中的事件處理被最小化。

我是正確的還是有反對我的期望的爭論?

我的第一個問題是,“最小化提供程序中的事件處理”是否重要? 也就是說,實現該目標有什么具體優勢?

我也想知道“意大利面事件”到底是什么意思。 我的意思是,它顯然引用了“意大利面條代碼”的古老概念,但是該概念是指執行路徑復雜的代碼,通常是由於使用了非結構化的流控制(即goto語句)。 在討論事件處理時,我看不到有什么類似意大利面條的。

換句話說,短語“意大利面”在這里似乎是有偏見的。 也就是說,“ spaghetti”一詞被扔掉了,因為它已經被理解為貶義詞。 但是缺乏明確的反對意見,貶義詞本身似乎是沒有道理的,而且“意大利面”一詞似乎並沒有像在“意大利面代碼”的上下文中那樣提供真正有用的隱喻。


因此,回到“最小化提供程序中的事件處理”。 為什么這很重要? 您寫道“這里的事件處理程序不是問題”,但這似乎表明提供程序中的處理程序適當的。 也就是說,他們所做的工作與提供者有關(可能與提供者有關)。 那么他們還怎么做呢?

以我的觀點(我寫的事實表明您的問題可能被認為是題外之意,“主要基於觀點”,但是我認為有一種客觀的方法可以查看此問題,即使那只是我的觀點:)) ,基於事件的編程模型的一大優點是減少了耦合。 假設必須在某處完成工作,預訂這些事件的提供程序對象的替代方法是讓其他一些對象了解提供程序對象的需求,並代表提供程序對象滿足這些需求。

但是,然后您只是用提供者對象的特定知識來裝載其他對象。 這增加了類型之間的耦合。 這通常是一件壞事


另一方面,如果您認為可以將提供程序中的事件處理程序移至其他類型而無需更強地耦合這些類型,則表明事件處理程序確實在提供程序中不合適。 但是,在那種情況下,與您的主張相反,這些事件處理程序的具體細節在此最相關。

事件處理程序推移取決於它的作用很大。 但是,由於您似乎並不關心這些處理程序的具體內容,因此這表明它們在它們所屬的位置正確,因此事件的訂閱完全不是問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM