首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

善用匿名函數與泛型基類優化快取讀取邏輯:實踐 DRY 原則

     編輯:關於ASP.NET

問題場景

應用程式大量使用快取時,常見模式為:

  1. 嘗試從快取讀取,命中則返回。
  2. 未命中則從資料源 (DB、API、服務) 取得資料。
  3. 將資料寫入快取並返回。

這段邏輯重複出現在許多方法中,違反 DRY (Don't Repeat Yourself) 原則,且當資料源存取涉及多類別協作、交易控制時,程式碼更顯冗長。

方案一:抽象基類封裝快取流程

定義泛型抽象類別 `CacheReader`,將固定流程集中在 `Read()` 方法,子類別只需實作三個抽象方法:

public abstract class CacheReader
{
    /// 從快取讀取,成功回傳 true 並輸出資料
    public abstract bool GetFromCache(out T data);

    /// 從資料源讀取資料
    public abstract T ReadFromSource();

    /// 將資料寫入快取
    public abstract void SetToCache(T data);

    /// 統一快取讀取流程
    public T Read()
    {
        if (GetFromCache(out T data)) return data;
        data = ReadFromSource();
        SetToCache(data);
        return data;
    }
}

具體實作範例

private class GetFriendCacheReader : CacheReader>
{
    private readonly int _userId;
    private readonly string _cacheKey;
    private readonly CacheManager _cacheManager;

    public GetFriendCacheReader(int userId, CacheManager cacheManager)
    {
        _userId = userId;
        _cacheKey = $"friends_of_user_{userId}";
        _cacheManager = cacheManager;
    }

    public override bool GetFromCache(out List data)
    {
        var obj = _cacheManager.Get(_cacheKey);
        if (obj == null) { data = null; return false; }
        data = (List)obj;
        return true;
    }

    public override List ReadFromSource()
        => new UserService().GetFriends(_userId);

    public override void SetToCache(List data)
        => _cacheManager.Set(_cacheKey, data);
}

呼叫方式

var reader = new GetFriendCacheReader(userId, cacheManager);
List friends = reader.Read();

方案二:使用匿名函數 (Lambda) 進一步簡化

若不想為每個查詢建立獨立類別,可設計接受委派的輔助方法:

public static class CacheHelper
{
    public static T GetOrAdd(string key, Func loader, TimeSpan? expiry = null)
    {
        if (CacheManager.Instance.TryGet(key, out T cached)) return cached;

        T value = loader();
        CacheManager.Instance.Set(key, value, expiry ?? TimeSpan.FromMinutes(30));
        return value;
    }
}

使用範例

// 簡潔的一行程式碼完成快取邏輯
var friends = CacheHelper.GetOrAdd(
    $"friends_of_user_{userId}",
    () => new UserService().GetFriends(userId),
    TimeSpan.FromHours(1)
);

比較與建議

維度基類模式Lambda 輔助方法
程式碼結構明確分離關注點,適合複雜邏輯極度精簡,適合簡單查詢
可測試性易於 Mock 抽象方法進行單元測試需 Mock 靜態方法或改用介面注入
擴充性可加入前後攔截、日誌、計量需修改輔助方法簽名
適用場景資料源存取複雜、需交易控制、多步驟組合單一查詢、快取鍵值固定、邏輯單純

總結

針對重複的快取讀取邏輯,採用「範本方法模式」封裝於基類,或使用「Lambda 輔助方法」簡化呼叫端,皆能有效落實 DRY 原則。專案中可依複雜度混合採用:核心業務查詢用基類確保可維護性,邊緣簡單查詢用 Lambda 提升開發速度。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved