簡體   English   中英

代碼復制最佳實踐 c#

[英]Best Practices on Code Duplication c#

我正在嘗試以減少/避免代碼重復的方式構造我的代碼,但我遇到了一個有趣的問題。 每次我的代碼調用存儲過程時,我都需要傳遞一些存儲過程共有的變量:例如用戶名、域、server_ip 和 client_ip。 這些都來自 HttpRequest object 或 system.environment object。

由於這些被傳遞給每個存儲過程,我最初的想法是創建一個實用程序 class ,它是一個數據庫包裝器,每次都會初始化並傳遞這些,所以我不必在我的代碼中這樣做。 問題是雖然 c# class(在 App_Code 文件夾內)沒有看到 Httprequest object。 當然,我可以將此作為參數傳遞給包裝器,但這會破壞創建包裝器的整個目的。 我在這里錯過了什么嗎?

我意識到每次調用存儲過程時重復 4 行代碼並不是什么大不了的事,但我寧願在早期階段消除代碼重復。

將數據層設置為從包含這些值的 4 個屬性的基礎 class 繼承。 使公共構造函數需要這 4 個屬性。

然后在業務層做一些類似的事情——在構造函數中使用這 4 個屬性來構建 class。

然后 UI 執行 new BusObj( Request["username"], ... ).method()

在數據層中,您可以有一個方法來構建具有這 4 個屬性的 SQLParameter 數組,然后每個方法都可以向數組添加其他參數。

作為一般規則,無論編程語言如何,如果您可以眯起眼睛並且代碼看起來相同,您應該從中創建一個函數/方法/消息並傳遞參數。

另一件事是,一旦您的方法采用大量參數(4 是一個很好的經驗法則,但它肯定是逐個案例的基礎),是時候讓該方法采用 object 作為參數而不是單個參數。 99.99999999999999999999% 的時間,這樣的 object 應該是不可變的(沒有可寫的實例變量)。

HttpContext.Current 與您在 HttpRequest 中找到的信息相似,更重要的是在 App_Code 中可用。

Here's a weird idea you may or may not like: define a 'profile' class and a function that expands the profile into the arguments of functions taking the common arguments.

class P {
    readonly string name;
    readonly string domain;
    public P(string name, string domain) {
        this.name = name; this.domain = domain;
    }
    public void inject(Action<string, string> f) {
        f(p.arg1, p.arg2);
    }
    public T inject<T>(Func<string, string, T> f) {
        return f(p.arg1, p.arg2);
    }
}

它可能在您擁有 AddressOf 運算符的 VB.net 中工作得更好。 我會非常謹慎地使用這種類型的東西,因為你很容易破壞可讀性和封裝性。

我會按照你現在的方式保留它。 它更干凈,更容易擴展/修改,更容易進行單元測試。

至於像其他人建議的那樣使用 HttpContext ,我會說這是一個壞主意。 一旦你開始在你的域中引入對 HttpContext 的依賴,就很難將其移除。 如果以后你想在沒有 HttpContext 的情況下使用你的模塊怎么辦? 那么單元測試呢?

嘗試 System.Web.HttpContext.Current.Request 獲取當前請求。

你可能正在滑下一個滑坡。 DRY 的要點是不要在多個地方重復業務邏輯,因為需求的變化會導致需要在多個相似的地方更改代碼。 如果這 4 行是上下文相關的,那么您不必僅僅因為 4 行是相同的而重構。 您還通過引用 httprequest 來破壞封裝,因為您使用的是全局變量。 作為 class 的消費者,我必須知道我只能從 web 應用程序中給您打電話的實現細節。

話雖如此,如果您考慮到這一點並仍想繼續,這里是此類信息的另一種選擇。 創建包含所需屬性的自定義 SecurityPrincipal(實現 IPrincipal)並將其附加到線程。 在用戶登錄時填寫它們,然后您可以在請求期間的任何地方訪問它。 您的調用者仍需要確保已完成此操作,但至少它不是特定於平台的。

否則,為了獲得最佳封裝,請將具有所需屬性的 class 傳遞到需要使用這些屬性的每個 object 的構造函數中。

暫無
暫無

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

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