最近事情多,中間還生病了一次,糾結(jié),最近一年來都沒有什么毛病,不知道咋了...頭痛..... 今天閑下來寫篇日志,頁面靜態(tài)化. 頁面靜態(tài)化是我們經(jīng)常碰到的問題,在web中,要說速度,只有html靜態(tài)頁面最快,所以頁面靜態(tài)化對于web網(wǎng)站來說,是一個非常好的減少請求降低服務(wù)器壓力的方式.
而常規(guī)的html靜態(tài)頁面也有很多問題,比如不能像php,aspx,jsp頁面那樣輕松的和數(shù)據(jù)庫交互. 在以前,html靜態(tài)化都是,對于一些子頁面(比如新聞內(nèi)容等),一旦發(fā)布基本上很少進(jìn)行修改的頁面,就可以通過數(shù)據(jù)庫讀取,然后生成html, 這種方式性能最好,而且對SEO友好,但不靈活,只對于那些很少修改的頁面,如果頁面發(fā)生修改又需要重新生成,這對于硬盤也是一種傷害. 于是乎,動態(tài)語言橫行. ajax技術(shù)的出現(xiàn),再度讓頁面進(jìn)入靜態(tài)化. html頁面中大量的ajax,即有很高的靈活性,而且達(dá)到的降低服務(wù)器壓力減少請求的目的. 但是這樣也會造成SEO的問題,所以,對于一些需要SEO的頁面就不要用ajax實現(xiàn)了. 那么哪些適合頁面靜態(tài)化呢? 對于那些私人的空間 比如:會員空間,大師空間,企業(yè)空間,登錄,注冊等等,這些地方,就不需要.
但是還有一個問題,對于這些頁面靜態(tài)化,我們經(jīng)常性都是先做aspx頁面(母板頁,用戶控件)等,最后做頁面靜態(tài)化操作,我們就需要重新把那些動態(tài)頁面的鏈接全部改成靜態(tài),這就太痛苦了,這時候我們就需要事先寫一個URL頁面靜態(tài)化管理,所有的鏈接經(jīng)過這個URLManage.GetURL處理. 1: /// <summary> 2: /// 獲得路徑(暫時只做靜態(tài)頁面管理)(/*在這里可以擴(kuò)展出URL重寫*/) 3: /// </summary> 4: /// <param name="PageUrl">頁面的URL(不包括擴(kuò)展名)</param> 5: /// <param name="QueryString">頁面參數(shù)</param> 6: /// <returns></returns> 7: public static string GetURL(string PageUrl,string QueryString) 8: { 9: //頁面路徑 10: string PagePath = ""; 11: 12: //如果當(dāng)前的參數(shù)不為空,則加上? 13: if (QueryString != "") 14: QueryString = "?" + QueryString; 15: //如果是靜態(tài)頁面(從配置文件中讀取靜態(tài)頁面狀態(tài)(是否)) 16: if (ReadURLConfig(PageUrl) == true) 17: { 18: PagePath = PageUrl + ".htm"; 19: } 20: //如果是動態(tài)頁面 21: else 22: PagePath = PageUrl + ".aspx"; 23: //把相對路徑轉(zhuǎn)化為絕對路徑 24: return System.Web.VirtualPathUtility.ToAbsolute(PagePath)+QueryString ; 25: } 26: /// <summary> 27: /// 從配置文件中讀取是否生成靜態(tài)頁面 28: /// </summary> 29: /// <param name="PageName">頁面的名稱</param> 30: /// <returns></returns> 31: public static bool ReadURLConfig(string PageURL) 32: { 33: //讀取配置文件 34: string path = HttpContext.Current.Server.MapPath(@"~/Admin/ConfigManage/URLConfig.xml"); 35: //XmlHelper.Read(path, "/Node/Element[@Attribute='Name']", "Attribute") 36: //是否生成HTML 37: string IsHtml="false"; 38: IsHtml=XMlHelper.Read(path, "/PageSettings/Page[@PageURL='"+PageURL+"']", "IsHtml"); 39: if (IsHtml.ToLower() == "true") 40: { 41: return true; 42: } 43: else return false; 44: 45: } 46: 這個類主要是幫助我們可以直接從配置文件中讀取關(guān)于文件頁面靜態(tài)化的信息 對于我們大量的ajax頁面(可能涉及到超鏈接),我們也需要通過這個URLManage來獲取他的路徑,由于js不能調(diào)用asp.net中的函數(shù),所以我們需要在每個頁面的開頭定義,js中需要用到的超鏈接. ![]() 看看它的ajax文件中是怎么寫的. 這時候,我們的前臺的工作就完成了,主要是后臺的頁面靜態(tài)化管理的設(shè)計了, 后臺的頁面靜態(tài)化管理,主要實現(xiàn),通過樹形菜單的形式,可以自由選擇,那些頁面生成靜態(tài)頁面,方便測試和維護(hù). 不過這里,少處理了關(guān)于新聞內(nèi)容的頁面靜態(tài)化,新聞內(nèi)容的頁面靜態(tài)化則是采用的第一種方法,完全的頁面靜態(tài)化,從數(shù)據(jù)庫讀取出數(shù)據(jù),全部生成的方式. 主要效果: 把需要頁面靜態(tài)化的頁面寫在配置文件中,然后通過這個頁面靜態(tài)化管理,進(jìn)行頁面靜態(tài)化. 這樣做的好處就是方便開發(fā)和維護(hù),可以很輕松的管理靜態(tài)頁面. 主要技術(shù): 1.XML操作以及LINQ簡單應(yīng)用, 2.頁面靜態(tài)化,只需要通過簡單的WebClient下載動態(tài)頁面就達(dá)到了頁面靜態(tài)化的目的.簡單方便.
WebClient下載文件類 1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Text; 5: using System.Net; 6: using System.Web; 7: using System.IO; 8: 9: namespace Common 10: { 11: /// <summary> 12: /// 用webClient下載文件 13: /// </summary> 14: public partial class DownFile 15: { 16: #region 生成靜態(tài)頁面 17: /// <summary> 18: /// 生成靜態(tài)頁面 19: /// 調(diào)用實例: 20: /// Common.DownFile webclient = new Common.DownFile(); 21: /// string RequestVirtualUrl= "/News/ViewNews.aspx?NewsId="+Info.Id; 22: /// string SaveVirtualPath = "~/News/" + Info.Id + ".htm"; 23: /// webclient.CreateStaticByWebClient(RequestVirtualUrl, SaveVirtualPath); 24: /// </summary> 25: /// <param name="VirtualRequestUrl">要請求的虛擬路徑,例如: "/News/ViewNews.aspx?NewsId="+Info.Id;</param> 26: /// <param name="SaveVirtualPath">要保存的虛擬路徑,例如:"~/News/" + Info.Id + ".htm";</param> 27: public static void CreateStaticByWebClient(string VirtualRequestUrl, string SaveVirtualPath) 28: { 29: WebClient wc = new WebClient(); 30: wc.Encoding = Encoding.UTF8; 31: //通過WebClient向服務(wù)器發(fā)Get請求,把服務(wù)器返回的html內(nèi)容保存到磁盤上,以后用戶直接請html文件請求. 32: string AppVirtualPath = HttpContext.Current.Request.ApplicationPath; 33: //由于網(wǎng)站應(yīng)用程序虛擬目錄是/czcraft,而傳遞過來/News是正確的, 34: //但是發(fā)布到iis上面,虛擬路徑就是/,而傳遞過來的確實/News,路徑就出錯了, 35: 36: if (AppVirtualPath == "/") 37: { 38: AppVirtualPath = ""; 39: } 40: string FilePath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + AppVirtualPath + VirtualRequestUrl; 41: 42: //保存路徑 43: string SaveFilePath = HttpContext.Current.Server.MapPath(SaveVirtualPath); 44: 45: //下載并保存文件 46: wc.DownloadFile(FilePath, SaveFilePath); 47: 48: } 49: #endregion 50: #region 文件刪除 51: /// <summary> 52: /// 文件刪除 53: /// </summary> 54: /// <param name="VirtualFilePath">文件虛擬路徑</param> 55: public void FileDelete(string VirtualFilePath) 56: { 57: //物理路徑 58: string RealFilePath = HttpContext.Current.Server.MapPath(VirtualFilePath); 59: 60: //如果文件存在則刪除 61: if (File.Exists(VirtualFilePath)) 62: { 63: File.Delete(VirtualFilePath); 64: } 65: } 66: #endregion 67: } 68: } 頁面靜態(tài)化管理類(URLXMLInfoManage): 1: using System; 2: using System.Data; 3: using System.Configuration; 4: using System.Linq; 5: using System.Web; 6: using System.Web.Security; 7: using System.Web.UI; 8: using System.Web.UI.HtmlControls; 9: using System.Web.UI.WebControls; 10: using System.Web.UI.WebControls.WebParts; 11: using System.Xml.Linq; 12: using System.Xml; 13: using System.Text; 14: using System.Collections; 15: using System.Collections.Generic; 16: using System.IO; 17: using Newtonsoft.Json; 18: 19: /// <summary> 20: ///URLXMLInfoManage 的摘要說明 21: /// </summary> 22: public class URLXMLInfoManage 23: { 24: #region 字段 25: //單例模式 26: public static readonly URLXMLInfoManage XMLInfo = new URLXMLInfoManage(); 27: /// <summary> 28: /// 路徑(XML) 29: /// </summary> 30: private static readonly string XMLPath = "~/Admin/ConfigManage/URLConfig.xml"; 31: #endregion 32: #region 實例化 33: /// <summary> 34: /// 私有實例化 35: /// </summary> 36: private URLXMLInfoManage() 37: { 38: } 39: /// <summary> 40: /// 實例化(靜態(tài)) 41: /// </summary> 42: /// <param name="path">xml的路徑</param> 43: /// <returns></returns> 44: public static URLXMLInfoManage Instance() 45: { 46: return XMLInfo; 47: } 48: #endregion 49: #region 通過頁面信息(返回json) 50: /// <summary> 51: /// 通過頁面信息(返回json) 52: /// </summary> 53: /// <returns></returns> 54: public string GetURLInfoForJson() 55: { 56: 57: //加載XML 58: XDocument xDoc = XDocument.Load(HttpContext.Current.Server.MapPath(XMLPath)); 59: 60: IEnumerable<XElement> PageList = xDoc.Root.Descendants("Page"); 61: //linq分組(根據(jù)xml中Page的Type的名稱分組 62: var group = PageList.GroupBy(page => page.Attribute("Type").Value); 63: //輸出json格式數(shù)據(jù) 64: StringBuilder json = new StringBuilder(); 65: StringWriter sw = new StringWriter(json); 66: using (JsonWriter jsonWriter = new JsonTextWriter(sw)) 67: { 68: jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented; 69: jsonWriter.WriteStartArray(); 70: foreach (IGrouping<string, XElement> item in group) 71: { 72: jsonWriter.WriteStartObject(); 73: //-1代表不存在的id 74: jsonWriter.WritePropertyName("id"); 75: jsonWriter.WriteValue(-1); 76: jsonWriter.WritePropertyName("text"); 77: jsonWriter.WriteValue(item.First().Attribute("TypeName").Value); 78: jsonWriter.WritePropertyName("expanded"); 79: jsonWriter.WriteValue(false); 80: jsonWriter.WritePropertyName("children"); 81: 82: jsonWriter.WriteStartArray(); 83: foreach (XElement XElem in item) 84: { 85: //頁面名稱 86: string PageName = XElem.Attribute("PageName").Value; 87: //頁面URL 88: string PageURL = XElem.Attribute("PageURL").Value; 89: //頁面標(biāo)識 90: string PageId = XElem.Attribute("Id").Value; 91: //是否是html頁面 92: bool IsHtml = Convert.ToBoolean(XElem.Attribute("IsHtml").Value); 93: jsonWriter.WriteStartObject(); 94: jsonWriter.WritePropertyName("id"); 95: jsonWriter.WriteValue(PageId); 96: jsonWriter.WritePropertyName("text"); 97: jsonWriter.WriteValue(PageName); 98: jsonWriter.WritePropertyName("expanded"); 99: jsonWriter.WriteValue(IsHtml); 100: jsonWriter.WriteEndObject(); 101: } 102: jsonWriter.WriteEndArray(); 103: 104: jsonWriter.WriteEndObject(); 105: 106: } 107: jsonWriter.WriteEndArray(); 108: 109: 110: 111: 112: } 113: return json.ToString(); 114: 115: 116: } 117: 118: #endregion 119: #region 設(shè)置頁面靜態(tài)化信息 120: /// <summary> 121: /// 設(shè)置頁面靜態(tài)化信息 122: /// </summary> 123: /// <param name="Ids"></param> 124: /// <returns></returns> 125: public bool SetURLInfo(string Ids) 126: { 127: //獲取URL的Id 128: string[] IdList = Ids.Split(','); 129: //加載XML 130: XDocument xDoc = XDocument.Load(HttpContext.Current.Server.MapPath(XMLPath)); 131: 132: IEnumerable<XElement> PageList = xDoc.Root.Descendants("Page"); 133: foreach (XElement Page in PageList) 134: { 135: //默認(rèn)不生成HTML頁面 136: Page.SetAttributeValue("IsHtml", false); 137: foreach (string Id in IdList) 138: { 139: 140: if (Id == Page.Attribute("Id").Value) 141: { 142: //頁面靜態(tài)化 143: CreateHTML(Page.Attribute("PageURL").Value); 144: //寫回XML中 145: Page.SetAttributeValue("IsHtml", true); 146: break; 147: } 148: } 149: } 150: xDoc.Save(HttpContext.Current.Server.MapPath(XMLPath)); 151: return true; 152: } 153: #endregion 154: #region 頁面靜態(tài)化(不適合文章等純HTML) 155: /// <summary> 156: /// 頁面靜態(tài)化(不適合文章等純HTML) 157: /// </summary> 158: /// <param name="PathURL"></param> 159: /// <returns></returns> 160: public bool CreateHTML(string PathURL) 161: { 162: 163: //保存路徑 164: string SavePath = PathURL + ".htm"; 165: //請求路徑(刪除前綴的~標(biāo)識) 166: string RequestPath = PathURL.TrimStart('~')+".aspx"; 167: //下載文件(原路徑保存) 168: Common.DownFile.CreateStaticByWebClient(RequestPath, SavePath); 169: return true; 170: } 171: #endregion 172: } 這里涉及到一個LINQ,以前沒怎么用過LINQ,僅僅是會點基本語法,這次,感覺真是挺強大的,簡潔清晰. //查找所有的Page節(jié)點 IEnumerable<XElement> PageList = xDoc.Root.Descendants("Page"); 以前我們也寫過類似的分組的處理,可以對比一下: 下面這個是根據(jù)類別,輸出前8個產(chǎn)品,跟上面是類似的. 可以看到LINQ的簡潔,LINQ和Lambda表達(dá)式,更簡潔,更清晰也更容易理解. 1: #region 根據(jù)企業(yè)id查找企業(yè)的產(chǎn)品信息(每種分別顯示前8個) 2: /// <summary> 3: /// 根據(jù)企業(yè)id查找企業(yè)的產(chǎn)品信息(每種分別顯示前8個) 4: /// </summary> 5: /// <param name="CompanyId"></param> 6: /// <returns></returns> 7: public string GetCompanyWorkForJson(string CompanyId) 8: { 9: //查詢狀態(tài) 10: bool Status = false; 11: //獲取企業(yè)的產(chǎn)品信息(每種顯示前8個) 12: DataTable dtListProduct = new VProductCraftTypeDAL().ListAllByCompanyIdToDatable(CompanyId); 13: //轉(zhuǎn)化為json格式 14: StringBuilder json = new StringBuilder(); 15: StringWriter sw = new StringWriter(json); 16: 17: using (JsonWriter jsonWriter = new JsonTextWriter(sw)) 18: { 19: 20: jsonWriter.Formatting = Formatting.Indented; 21: //判斷數(shù)據(jù)讀取狀態(tài) 22: if (dtListProduct.Rows.Count > 0) 23: { 24: Status = true; 25: } 26: jsonWriter.WriteStartObject(); 27: jsonWriter.WritePropertyName("Status"); 28: jsonWriter.WriteValue(Status); 29: jsonWriter.WritePropertyName("Data"); 30: 31: jsonWriter.WriteStartArray(); 32: if (Status == true) 33: { 34: //先輸出第一個元素的類別信息 35: jsonWriter.WriteStartObject(); 36: jsonWriter.WritePropertyName("TypeId"); 37: jsonWriter.WriteValue(dtListProduct.Rows[0]["TypeId"].ToString()); 38: jsonWriter.WritePropertyName("TypeName"); 39: jsonWriter.WriteValue(dtListProduct.Rows[0]["TypeName"].ToString()); 40: //第一個元素的開始 41: jsonWriter.WritePropertyName("Product"); 42: jsonWriter.WriteStartArray(); 43: 44: //按照類別分組 45: //產(chǎn)品計數(shù)(一個分組下的產(chǎn)品,從1開始算起) 46: 47: for (int num = 0, numProduct = 1; num < dtListProduct.Rows.Count; num++, numProduct++) 48: { 49: 50: //獲取該類別下的分組總個數(shù) 51: int Total = Convert.ToInt32(dtListProduct.Rows[num]["total"]); 52: //如果該類別下還存在未輸出的產(chǎn)品 53: if (numProduct <= Total) 54: { 55: 56: 57: jsonWriter.WriteStartObject(); 58: jsonWriter.WritePropertyName("ProductId"); 59: jsonWriter.WriteValue(dtListProduct.Rows[num]["Id"].ToString()); 60: jsonWriter.WritePropertyName("Name"); 61: jsonWriter.WriteValue(dtListProduct.Rows[num]["Name"].ToString()); 62: jsonWriter.WritePropertyName("SimpleName"); 63: jsonWriter.WriteValue(dtListProduct.Rows[num]["SimpleName"].ToString()); 64: jsonWriter.WritePropertyName("Lsprice"); 65: jsonWriter.WriteValue(dtListProduct.Rows[num]["Lsprice"].ToString()); 66: jsonWriter.WritePropertyName("Picturepath"); 67: jsonWriter.WriteValue(dtListProduct.Rows[num]["Picturepath"].ToString()); 68: jsonWriter.WriteEndObject(); 69: 70: } 71: else 72: { 73: //將該類別的產(chǎn)品計數(shù)重置為1 74: numProduct = 1; 75: //這里給上一個類別的產(chǎn)品結(jié)束標(biāo)記 76: 77: jsonWriter.WriteEndArray(); 78: jsonWriter.WriteEndObject(); 79: 80: jsonWriter.WriteStartObject(); 81: jsonWriter.WritePropertyName("TypeId"); 82: jsonWriter.WriteValue(dtListProduct.Rows[num]["TypeId"].ToString()); 83: jsonWriter.WritePropertyName("TypeName"); 84: jsonWriter.WriteValue(dtListProduct.Rows[num]["TypeName"].ToString()); 85: //如果還存在產(chǎn)品 86: if (num < dtListProduct.Rows.Count) 87: { 88: //下一個元素的開始 89: jsonWriter.WritePropertyName("Product"); 90: jsonWriter.WriteStartArray(); 91: 92: } 93: 94: } 95: } 96: } 97: 98: 99: jsonWriter.WriteEndArray(); 100: jsonWriter.WriteEndObject(); 101: 102: } 103: return json.ToString(); 104: } 105: #endregion 接下來我們就可以寫,UI層和業(yè)務(wù)層了, UI層仍然是用的MUNIUI框架(以后再也不用這個了,其實,不太好用,感覺,換個其他的JQuery框架), 1: 2: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd"> 3: <html xmlns="http://www./1999/xhtml"> 4: <head> 5: <title>頁面管理(靜態(tài)頁面生成管理)</title> 6: <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 7: <link href="../css/demo.css" rel="stylesheet" type="text/css" /> 8: 9: <script src="../scripts/jquery-1.6.2.min.js" type="text/javascript"></script> 10: 11: <script src="../scripts/miniui/miniui.js" type="text/javascript"></script> 12: 13: <link href="../scripts/miniui/themes/default/miniui.css" rel="stylesheet" type="text/css" /> 14: <link href="../scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" /> 15: </head> 16: <body> 17: <h1> 18: 頁面靜態(tài)化管理</h1> 19: <ul id="tree2" class="mini-tree" url="Data/UrlInfo.ashx?method=GetURLInfo" style="width: 300px;" 20: showtreeicon="true" textfield="text" idfield="id" showcheckbox="true" 21: checkrecursive="true"> 22: </ul> 23: <br /> 24: 25: <a class="mini-button" iconCls=" icon-new" href="javascript:ToHtml()">頁面靜態(tài)化</a> 26: <!-- <input type="button" value="setCheckedNodes" onclick="setCheckedNodes()" /> 27: <input type="button" value="getCheckedNodes" onclick="getCheckedNodes()" />--> 28: <br /> 29: 30: <script type="text/javascript"> 31: 32: 33: function getCheckedNodes() { 34: var tree = mini.get("tree2"); 35: var value = tree.getValue(); 36: alert(value); 37: 38: } 39: //頁面靜態(tài)化 40: function ToHtml(){ 41: var tree = mini.get("tree2"); 42: var value = tree.getValue(); 43: if(value==null){ 44: alert("請選擇要生成的靜態(tài)頁面的頁面名稱"); 45: return; 46: } 47: else{ 48: //alert(value); 49: $.ajax({ 50: url: "Data/UrlInfo.ashx?method=ToHtml", 51: data:{Id:value}, 52: cache: false, 53: success: function (text){ 54: if(text) 55: { 56: alert("頁面HTML生成成功!"); 57: } 58: } 59: }); 60: 61: } 62: 63: } 64: //-------------------------------- 65: function onBeforeCheckNode(e) { 66: var tree = e.sender; 67: var node = e.node; 68: if (tree.hasChildren(node)) { 69: //e.cancel = true; 70: } 71: } 72: 73: </script> 74: 75: 76: </body> 77: </html> 78: 后臺Ashx頁面: 1: <%@ WebHandler Language="C#" Class="UrlInfo" %> 2: 3: using System; 4: using System.Web; 5: using czcraft.BLL; 6: using czcraft.Model; 7: using Common; 8: using System.Collections.Generic; 9: using Newtonsoft.Json.Linq; 10: public class UrlInfo : IHttpHandler { 11: 12: 13: public void ProcessRequest(HttpContext context) 14: { 15: String methodName = context.Request["method"]; 16: if (!string.IsNullOrEmpty(methodName)) 17: CallMethod(methodName, context); 18: } 19: /// <summary> 20: /// 根據(jù)業(yè)務(wù)需求調(diào)用不同的方法 21: /// </summary> 22: /// <param name="Method">方法</param> 23: /// <param name="context">上下文</param> 24: public void CallMethod(string Method, HttpContext context) 25: { 26: switch (Method) 27: { 28: case "GetURLInfo": 29: GetURLInfo(context); 30: break; 31: case "ToHtml": 32: ToHtml(context); 33: break; 34: default: 35: return; 36: 37: 38: } 39: } 40: /// <summary> 41: /// 頁面html 42: /// </summary> 43: /// <param name="context"></param> 44: public void ToHtml(HttpContext context) 45: { 46: string Ids= context.Request["Id"]; 47: 48: URLXMLInfoManage xmlManage = URLXMLInfoManage.Instance(); 49: //寫回XML中 50: context.Response.Write(xmlManage.SetURLInfo(Ids)); 51: } 52: /// <summary> 53: /// 獲取URL信息(生成html的) 54: /// </summary> 55: /// <param name="context"></param> 56: public void GetURLInfo(HttpContext context) 57: { 58: URLXMLInfoManage xmlManage = URLXMLInfoManage.Instance(); 59: 60: context.Response.Write(xmlManage.GetURLInfoForJson()); 61: } 62: public bool IsReusable { 63: get { 64: return false; 65: } 66: } 67: 68: } 頁面靜態(tài)化效果: 可以看到首頁和右下角的超鏈接,后綴都變成了htm,而且,項目中可以看到都生成了html頁面
最近再看3本好書,一本是.net設(shè)計規(guī)范 極品,看了之后才知道代碼命名等等問題. 還有一本是博客園的. 小洋(燕洋天)寫的,蠻不錯的,叫做.net應(yīng)用架構(gòu)設(shè)計原則,模式與實踐 比較適合我這種,web對于架構(gòu)方面有點感覺,但是不知道怎么樣設(shè)計的好,擴(kuò)展性好的孩紙. 還有一本就是C# in Depth 買了本英文版,慢慢品讀,學(xué)英語,英語太差真吃虧呀! 接下來就是寫一個緩存管理, 以前設(shè)計的緩存,只適合asp.net的Cache,但是asp.net的緩存,不適合大型構(gòu)架,大型構(gòu)架都會把緩存單獨放在緩存服務(wù)器中,經(jīng)常性,別人擴(kuò)展到大型應(yīng)用就麻煩了,我們需要考慮周全就需要寫一個可擴(kuò)展性的緩存結(jié)構(gòu), MemCache是一個很強力的高性能分布式緩存系統(tǒng).接下來就準(zhǔn)備設(shè)計一個緩存管理組件,用來管理緩存,如果網(wǎng)站擴(kuò)大可以輕松的把緩存往MemCache上移植. |
|