自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

對(duì)設(shè)計(jì)及重構(gòu)的一點(diǎn)反思

開(kāi)發(fā) 架構(gòu)
本項(xiàng)目是一個(gè)電子商務(wù)類(lèi)的網(wǎng)站,其中有個(gè)功能是在訂單狀態(tài)改變到某種狀態(tài)后向客戶(hù)發(fā)送通知短信的功能,短信及網(wǎng)關(guān)功能均已封裝為組建的方式,我們直接調(diào)用即可。

本文是我對(duì)一個(gè)項(xiàng)目中一個(gè)小功能點(diǎn)的演進(jìn)及重構(gòu)過(guò)程的一點(diǎn)反思與心得。

背景:

本項(xiàng)目是一個(gè)電子商務(wù)類(lèi)的網(wǎng)站,其中有個(gè)功能是在訂單狀態(tài)改變到某種狀態(tài)后向客戶(hù)發(fā)送通知短信的功能,短信及網(wǎng)關(guān)功能均已封裝為組建的方式,我們直接調(diào)用即可。

為更清晰明白地說(shuō)明與本主題相關(guān)的功能,在此我以一個(gè)控制臺(tái)的程序方式說(shuō)明代碼的演進(jìn)過(guò)程。

重構(gòu)的演進(jìn)過(guò)程:

最初我們是如大多數(shù)項(xiàng)目一樣,為在規(guī)定的時(shí)間內(nèi)完成相關(guān)功能點(diǎn)而努力奮斗著,這個(gè)功能點(diǎn)的主要代碼如下:

  1. v1   
  2.  
  3.         static void SendSMS_V1(DataTable dt)  
  4.         {  
  5.             if (null == dt) return;  
  6.  
  7.             for (int i = 0; i < dt.Rows.Count; i++)  
  8.             {  
  9.                 var row = dt.Rows[i];  
  10.                 OrderStateEnum state = (OrderStateEnum)((int)row["OrderState"]);  
  11.                 string template = string.Empty;  
  12.                 switch (state)  
  13.                 {  
  14.                     case OrderStateEnum.UnConfirmed:  
  15.                         template = "尊敬的{0},你好!你的訂單已成功下達(dá),請(qǐng)盡快付款以便配送。";  
  16.                         break;  
  17.                     case OrderStateEnum.Confirmed:  
  18.                         template = "尊敬的{0},你好!你的訂單(訂單號(hào):{1})已被確認(rèn),請(qǐng)耐心等待。";  
  19.                         break;  
  20.                     case OrderStateEnum.Cancel:  
  21.                         template = "尊敬的{0},你好!你的訂單(訂單號(hào):{1})已被取消,具體原因請(qǐng)上網(wǎng)查看。";  
  22.                         break;  
  23.                     case OrderStateEnum.Finish:  
  24.                         template = "尊敬的{0},你好!你的訂單(訂單號(hào):{1})已完成,網(wǎng)站感謝您的支持與配合,歡迎再次光臨。";  
  25.                         break;  
  26.                     default:  
  27.                         break;  
  28.                 }  
  29.  
  30.                 string content = string.Format(template, row["CustomerName"], row["OrderID"]);  
  31.                 SendSMS.Send(row["phone"].ToString(), content);  
  32.             }  
  33.         } 

在項(xiàng)目上線初期,這段代碼工作良好。

在運(yùn)營(yíng)一段時(shí)間后運(yùn)營(yíng)部門(mén)同事陸續(xù)提出要在某些地方將產(chǎn)品名稱(chēng)給加上去,在這一改動(dòng)過(guò)程中,我發(fā)現(xiàn)代碼沒(méi)有和數(shù)據(jù)相分離,再者如要增加一個(gè)訂單狀態(tài)后增加相應(yīng)的短信提示或者取消某一個(gè)狀態(tài)的短信提示,這個(gè)改動(dòng)過(guò)程有點(diǎn)麻煩。于是初步想到將短信的內(nèi)容放到配置文件中,在調(diào)用的時(shí)候讀取訂單狀態(tài)對(duì)應(yīng)的配置文件然后格式化即可。如讀取的內(nèi)容為空或者該文件不存在則跳過(guò)不發(fā)送。主要代碼如下:

  1. v2 內(nèi)容和數(shù)據(jù)分離   
  2.  
  3.         #region v2 內(nèi)容和數(shù)據(jù)分離   
  4.         static void SendSMS_V2(DataTable dt)  
  5.         {  
  6.             if (null == dt) return;  
  7.  
  8.             for (int i = 0; i < dt.Rows.Count; i++)  
  9.             {  
  10.                 var row = dt.Rows[i];  
  11.                 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SMSTemplates",  
  12.                     "V2", row["OrderState"].ToString() + ".txt");  
  13.  
  14.                 var template = FileHelper.Read(path);  
  15.                 if (!string.IsNullOrEmpty(template)) {  
  16.                     string content = string.Format(template, row["CustomerName"], row["OrderID"], row["ProductName"]);  
  17.                     SendSMS.Send(row["phone"].ToString(), content);  
  18.                 }  
  19.             }  
  20.         }  
  21.         #endregion 

模版

  1. 尊敬的{0},你好!你的訂單(訂單號(hào):{1})已被確認(rèn),請(qǐng)耐心等待。 

隨著運(yùn)營(yíng)進(jìn)行,運(yùn)營(yíng)部門(mén)不斷地提出將某些字段在某些地方顯示, string.Format 后的參數(shù)不斷地增加,每次改后都要將整個(gè)過(guò)程重新測(cè)試一通,很是讓人頭疼!我的想法是開(kāi)發(fā)這邊提供一個(gè)數(shù)據(jù)標(biāo)簽列表,同時(shí)在后臺(tái)提供操作界面將短信管理模板讓運(yùn)營(yíng)同事自己去修改,不用每次都找我們?有了以上想法,使用一個(gè)自定義的 formatter :

  1. 自定義參數(shù)格式化   
  2.  
  3.     public class IndexerNamedFormatter : IFormatProvider, ICustomFormatter  
  4.     {  
  5.         public IndexerNamedFormatter() { }  
  6.  
  7.         public object GetFormat(Type formatType)  
  8.         {  
  9.             if (formatType == typeof(ICustomFormatter))  
  10.                 return this;  
  11.  
  12.             throw new TypeAccessException("不匹配的類(lèi)型。");  
  13.         }  
  14.  
  15.         public string Format(string format, object arg, IFormatProvider formatProvider)  
  16.         {  
  17.             if (null == arg)  
  18.                 throw new ArgumentNullException("參數(shù) arg 不能為 null");  
  19.  
  20.             int indexer = 0;  
  21.             bool isIndexed = int.TryParse(format, out indexer);  
  22.  
  23.             //如是 datarow   
  24.             if (arg is System.Data.DataRow)  
  25.             {  
  26.                 return GetStringFromDataRow(format, arg, indexer, isIndexed);  
  27.             }  
  28.  
  29.             //如是 datareader 之類(lèi)的  
  30.             if (arg is System.Data.IDataRecord)  
  31.             {  
  32.                 GetStringFromIDataRecord(format, arg, indexer, isIndexed);  
  33.             }  
  34.  
  35.             return string.Empty; ;  
  36.  
  37.         }  
  38.  
  39.         private static void GetStringFromIDataRecord(string format, object arg, int indexer, bool isIndexed)  
  40.         {  
  41.             var dr = (System.Data.IDataRecord)arg;  
  42.             string.Format("{0}", isIndexed ? dr[indexer] : dr[format]);  
  43.         }  
  44.  
  45.         string GetStringFromDataRow(string format, object arg, int indexer, bool isIndexed)  
  46.         {  
  47.             var row = (System.Data.DataRow)arg;  
  48.             return string.Format("{0}", isIndexed ? row[indexer] : row[format]);  
  49.         } 
  1. v3 使用自定義標(biāo)簽   
  2.  
  3. #region v3 使用自定義標(biāo)簽   
  4.         static void SendSMS_V3(DataTable dt)  
  5.         {  
  6.             if (null == dt) return;  
  7.  
  8.             IndexerNamedFormatter formatter = new IndexerNamedFormatter();  
  9.             for (int i = 0; i < dt.Rows.Count; i++)  
  10.             {  
  11.                 var row = dt.Rows[i];  
  12.                 string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SMSTemplates",  
  13.                     "V3", row["OrderState"].ToString() + ".txt");  
  14.  
  15.                 var template = FileHelper.Read(path);  
  16.                 if (!string.IsNullOrEmpty(template))  
  17.                 {  
  18.                     string content = string.Format(formatter,  
  19.                         template, row);  
  20.                     SendSMS.Send(row["phone"].ToString(), content);  
  21.                 }  
  22.             }  
  23.         }  
  24.         #endregion 

模版

  1. 尊敬的{0:CustomerName},你好!你的訂單(訂單號(hào):{0:OrderID},產(chǎn)品:產(chǎn)品{0:productname})已被確認(rèn),請(qǐng)耐心等待。 

將數(shù)據(jù)字段取出來(lái)后寫(xiě)成一個(gè)標(biāo)簽列表文檔提供給運(yùn)營(yíng)人員后,從此關(guān)于這一塊的修改要求安靜了。

以上只是一個(gè)小小設(shè)計(jì)技巧,這也讓我明白需求的準(zhǔn)確把握與挖掘是何等地重要!往往客戶(hù)今天說(shuō)要這樣,明天要那樣,大概很多人都在抱怨:你們真麻煩!但在需求不斷地出現(xiàn)時(shí)我們是不是在修改的時(shí)候也反思下是不是我們未準(zhǔn)確把握他們所想要的功能而讓功能設(shè)計(jì)出了點(diǎn)問(wèn)題?當(dāng)然我也不崇尚一開(kāi)始就大談設(shè)計(jì),過(guò)度設(shè)計(jì)要付出大量的時(shí)間成本和可能導(dǎo)致實(shí)現(xiàn)的復(fù)雜度的增加。

一點(diǎn)疑問(wèn):

通過(guò)查閱文檔我一直感覺(jué) arg is System.Data.DataRow 這種實(shí)現(xiàn)方式很是別扭,為什么索引器不定義為一個(gè)接口 ?有誰(shuí)有更好的實(shí)現(xiàn)方法麻煩告知,謝謝!

感謝您的閱讀!文中所涉及到的代碼可從此下載。

原文鏈接:http://www.cnblogs.com/infozero/archive/2013/03/05/2944106.html

責(zé)任編輯:林師授 來(lái)源: 博客園
相關(guān)推薦

2015-12-04 15:39:27

產(chǎn)品服務(wù)反思

2014-09-17 10:30:25

代碼

2015-11-02 09:43:25

ASP.NET異步編程

2021-05-17 11:47:41

多租戶(hù)系統(tǒng)私有化

2010-05-20 15:29:43

優(yōu)化IIS

2013-05-14 12:06:26

.Net系統(tǒng)架構(gòu)架構(gòu)設(shè)計(jì)

2013-05-13 11:25:44

系統(tǒng)架構(gòu)

2009-04-13 11:50:14

經(jīng)驗(yàn)交流職業(yè)分析面試

2009-07-09 15:09:05

JDK卸載

2012-03-27 08:49:19

Json

2009-09-14 19:44:27

LINQ To SQL

2009-07-22 14:53:45

ibmdwIT架構(gòu)

2016-04-05 10:12:58

HiveSQLHadoop

2024-05-31 08:40:09

2016-01-06 09:49:59

青云/SDN

2009-09-14 20:17:05

并行LINQ

2014-06-04 10:48:38

Swift蘋(píng)果iOS

2012-07-12 10:49:53

項(xiàng)目管理

2011-07-04 09:33:04

惠普轉(zhuǎn)型李艾科

2014-07-24 13:32:01

Google NowSiri
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)