標籤:des blog io 使用 ar 資料 sp 問題 代碼
在業務制定的時候很少會切入緩衝設計這一環節,畢竟在指標不明確的情況這屬於一種過渡設計.畢竟緩衝切入有很多手段,在很多時候直接在WEB進行一個頁面緩衝就有著非常高收益的效果.緩衝是一種橫向的資料處理應用,一般在設計中引入AOP,ICO的應用組件都可以在後期切入添加.但AOP,ICO在沒有比較豐富的經驗情況引入會直接增加應用的複雜度和風險.在設計主要介紹一種簡單的設計方式在設計階段引用緩衝但又不帶來複雜的工作成本.
一個簡單樣本
public class BlogService:Interfaces.IBlogService { public IList<Blog> List(string category, int size, int index, out int pages) { Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count<Blog>(); pages = count / size; if (count % size > 0) pages++; return exp.List<Blog>(new Region(index, size), Blog.createTime.Desc); } public IList<BlogCategory> ListCategories() { return new Expression().List<BlogCategory>(); } public Blog Get(string id) { return (Blog.iD == id).ListFirst<Blog>(); }}
以上是一個完全不考慮緩衝應用的情況,一般在前期都這樣做,畢竟完成功能是首要面對的問題.
簡單加入緩衝
以List方法為例加入緩衝處理方式.
public IList<Blog> List(string category, int size, int index, out int pages) { IList<Blog> result = redis.Get<IList<Blog>>("key"); if (result == null) { Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count<Blog>(); pages = count / size; if (count % size > 0) pages++; result = exp.List<Blog>(new Region(index, size), Blog.createTime.Desc); redis.Set("key", result); } return result; }
這一平時在開發中看到比較的方式,說實話一開始考慮這樣做的確是增加比較大的工作量,特別在前期階段沒有效能要求的情況,這隻會增長工作和延時進度.還有就是緩衝產品的偶合性也強達不到比較好的秀明度;畢竟開發人員還要學習具體緩衝產品的API.
緩衝實現的解偶
可以在設計的時候制定一個簡單的緩衝儲提供者.
public interface ICached { T Get<T>(string key); void Set(string key, object data); }
在設計的時候引入到介面定義中
public interface IBlogService { IList<Blog> List(string category, int size, int index, out int pages); Blog Get(string id); Blog Save(string id, string title, string keywords, string data, params string[] categories); IList<BlogCategory> ListCategories(); ICached Cached { get; set; } }
這樣一個簡單針對邏輯層的Cached應用規範就出來了.這樣可以大大降低了開發人員對緩衝產品依賴;當然這個介面設計的簡陋,在設計時有可能需要考慮逾時設定等等.雖然解偶的目的達到了,但使用方便性上還是比較麻煩,工作並沒有多大的減少.
緩衝應用簡化
其實在介面針對Get定義一些簡單的委託參數可以簡單Cache在應用時的複發度.
public interface ICached { T Get<T>(Func<T> handler, string key); void Set(string key, object data); }
那在編寫邏輯的時候就比較簡單一些
{ public IList<Blog> List(string category, int size, int index, out int pages) { dynamic eo = Cached.Get<dynamic>(() => { dynamic result = new ExpandoObject(); Expression exp = new Expression(); if (!string.IsNullOrEmpty(category)) exp &= Blog.iD == BlogLinkCategory.blog[BlogLinkCategory.category == category]; int count = exp.Count<Blog>(); result.Pages = count / size; if (count % size > 0) result.Pages++; result.Blogs = exp.List<Blog>(new Region(index, size), Blog.createTime.Desc); return result; }, key); pages = eo.Pages; return eo.Blogs; }
其實原理比較簡單,就是Get內部實現如果相關key不存在的情況直接執行Func<T>的方法得到資料,並設定到緩衝中.以上需要處理一些條件和分頁返回所以感覺會複雜一些.一般代碼下都簡單.
public TextBlock GetByTitle(string title) { return Cached.Get<TextBlock>(() => (TextBlock.iD == title).ListFirst<TextBlock>(),title); }
如果再花點小心思,那可以這樣子
public User Get(string name) { return (User.name == name).ListFirst<User>(); } public User Get(string name) { return Cached[name].Get<User>(() => { return (User.name == name).ListFirst<User>(); }); }
這樣基於在外面套一層Cached應用代碼,裡面的代碼是不用修改.
總結
通過這樣的設計在邏輯層或其他層面引用緩衝設計並不會對整個代碼帶來多大的複雜度變化,剛開始完全可以引用一個完全都不做的ICached實現.在後期有需要的話直接更換代碼.文章裡的ICached的設計比較簡陋畢竟只是用於體現這種設計模式而已.如果業務場複雜的情況這個ICached所反映的行為參數可能會複雜一些.不過開發人員總會有辦法把複雜的調用變成簡單的.
商務邏輯層緩衝應該設計