国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 課堂 > 技術(shù)開發(fā) > 正文

利用AOP重構(gòu)代碼

2023-06-23 14:40:29
字體:
供稿:網(wǎng)友

AOP是什么?

AOP是OOP的延續(xù),Aspect Oriented Programming的縮寫,即面向方面編程。AOP是GoF設(shè)計(jì)模式的延續(xù),設(shè)計(jì)模式追求的是調(diào)用者和被調(diào)用者之間的解耦,AOP也是這種目標(biāo)的一 種實(shí)現(xiàn)。

案例:在應(yīng)用程序中,我們經(jīng)常會(huì)對(duì)某一段程序做異常處理,或者是把一個(gè)方法的調(diào)用所消耗的時(shí)間體現(xiàn)在日志中,如果我們對(duì)每個(gè)方法都寫具體的實(shí)現(xiàn),我想并不是一件輕松的事情。對(duì)于異常處理來講,其實(shí)我們平常編程很少去捕獲具體的異常,當(dāng)然特殊程序除外,例如客戶端捕獲WCF異常時(shí)最好捕獲CommunicationException,TimeoutException,Exception。否則一般都會(huì)直接捕獲Exception,因?yàn)楹芏喈惓M且饬现獾漠惓!?duì)于記錄方法調(diào)用時(shí)間問題,我想也非常麻煩,下面例子簡(jiǎn)單的展示了記錄時(shí)間:當(dāng)你需要對(duì)多個(gè)方法都需要記錄時(shí)間時(shí),這些代碼往往讓人感覺有重構(gòu)的必要。 

Stopwatch sw = new Stopwatch();
   sw.Start();
   
//方法執(zhí)行.....
   sw.Stop();
   WebLog.SquareLog.CommonLogger.Error(
"取積分廣場(chǎng)首頁(yè)酒店數(shù)據(jù)用時(shí):"+sw.ElapsedMilliseconds .ToString ()+"毫秒");

上面的記錄方法調(diào)用用時(shí),如果抽象出來,其實(shí)有下列特性: 

(1)不是具體訪問類的首要或主要功能,訪問類主要功能是業(yè)務(wù)邏輯處理。

(2)具體訪問類的主要功能可以獨(dú)立、區(qū)分開來的。 

(3)是這個(gè)系統(tǒng)的一個(gè)縱向切面,涉及多個(gè)類、多個(gè)類的方法。示意圖如下:

aspect:  新的程序結(jié)構(gòu)關(guān)注系統(tǒng)的縱向切面,例如這里的異常處理以及方法調(diào)用時(shí)間記錄,這個(gè)新的程序結(jié)構(gòu)就是aspect(方面),方面(aspect)應(yīng)該有以下職責(zé):提供一些必備的功能,對(duì)被訪問對(duì)象實(shí)現(xiàn)特有功能,以保證所以方法在被執(zhí)行時(shí)都能正常的執(zhí)行異常處理或者是其它的功能。

AOP應(yīng)用范圍

(1)Authentication 權(quán)限

(2)Error handling 錯(cuò)誤處理

(3)logging, tracing, profiling and monitoring 記錄跟蹤 優(yōu)化 校準(zhǔn)

 ......

AOP具體實(shí)現(xiàn):主要是利用泛型委托來實(shí)現(xiàn)AOP思想。但泛型委托有一個(gè)局限就是最多支持四個(gè)參數(shù),當(dāng)你的方法超過四個(gè)時(shí)就不太好應(yīng)用AOP重構(gòu)了。我最近分析了有以下三個(gè)地方我們可以對(duì)代碼進(jìn)行優(yōu)化:

第一:普通方法異常處理:ErrorHandler類,實(shí)現(xiàn)類參考第二或者是第三。

客戶端調(diào)用:

string ErrorMethodText="取積分廣場(chǎng)首頁(yè)酒店數(shù)據(jù)異常:";
           list 
= ErrorWCFHandler .Invoke<ISearchHotelForSquare, List<HotelGenericInfo>>(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList() ); 

第二:客戶端調(diào)用WCF的異常處理:ErrorWCFHandler。

代碼:

public  class ErrorWCFHandler
    {
       
public static void Invoke<TContract>(TContract proxy, Action<TContract> action, string MethodElapsedTimeText, string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
try
            {
                action(proxy);
                (proxy 
as ICommunicationObject).Close();
            }
            
catch (CommunicationException ex)
            {
                (proxy 
as ICommunicationObject).Abort();
                
//Handle Exception             
                
//throw;
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            
catch (TimeoutException ex)
            {
                (proxy 
as ICommunicationObject).Abort();
                
//Handle Exception         
                
//throw;
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            
catch (Exception ex)
            {
                
//Handle Exception        
                
//(proxy as ICommunicationObject).Close();      
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText 
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
        }
       
public static TReturn Invoke<TContract, TReturn>(TContract proxy, Func<TContract, TReturn> func, string MethodElapsedTimeText, string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            TReturn returnValue 
= default(TReturn);
            
try
            {
                returnValue 
= func(proxy);
            }
            
catch (CommunicationException ex)
            {
                (proxy 
as ICommunicationObject).Abort();
                
//Handle Exception     
                
//throw;
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            
catch (TimeoutException ex)
            {
                (proxy 
as ICommunicationObject).Abort();
                
//Handle Exception       
                
//throw;
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            
catch (Exception ex)
            {
                
//Handle Exception  
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());
            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText 
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
            
return returnValue;
        }
    }

客戶端調(diào)用:

string ComputationTimeText="取積分廣場(chǎng)首頁(yè)酒店數(shù)據(jù)耗時(shí):";
           
string ErrorMethodText="取積分廣場(chǎng)首頁(yè)酒店數(shù)據(jù)異常:";
           list 
= ErrorWCFHandler .Invoke<ISearchHotelForSquare, List<HotelGenericInfo>>(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList

(),ComputationTimeText ,ErrorMethodText );  

 

第三:記錄方法調(diào)用時(shí)間,這中間也增加了異常處理:ErrorAndComputationTimeHandler

代碼:

 public class ErrorAndComputationTimeHandler
    {
        
public static void Invoke<TContract>(TContract proxy, Action<TContract> action, string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
try
            {
                action(proxy);

            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
        }
        
public static void Invoke<TContract, TContract2>(TContract proxy, TContract2 proxy2, Action<TContract, TContract2> action, string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
try
            {
                action(proxy, proxy2);

            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
        }
        
public static void Invoke<TContract, TContract2, TContract3>(TContract proxy, TContract2 proxy2, TContract3 proxy3, Action<TContract, TContract2, TContract3> action, string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
try
            {
                action(proxy, proxy2, proxy3);

            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
        }
        
public static void Invoke<TContract, TContract2, TContract3, TContract4>(TContract proxy, TContract2 proxy2, TContract3 proxy3, TContract4 proxy4, Action<TContract, TContract2, TContract3, TContract4> action,  string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            
try
            {
                action(proxy, proxy2, proxy3, proxy4);

            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
        }
        
public static TReturn Invoke<TContract, TReturn>(TContract proxy, Func<TContract, TReturn> func,  string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            TReturn returnValue 
= default(TReturn);
            
try
            {
                returnValue 
= func(proxy);
            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
            
return returnValue;
        }
        
public static TReturn Invoke<TContract, TContract2, TReturn>(TContract proxy, TContract2 proxy2, Func<TContract, TContract2, TReturn> func,  string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            TReturn returnValue 
= default(TReturn);
            
try
            {
                returnValue 
= func(proxy, proxy2);
            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
            
return returnValue;
        }
        
public static TReturn Invoke<TContract, TContract2, TContract3, TReturn>(TContract proxy, TContract2 proxy2, TContract3 proxy3, Func<TContract, TContract2, TContract3, TReturn> func,  string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            TReturn returnValue 
= default(TReturn);
            
try
            {
                returnValue 
= func(proxy, proxy2, proxy3);
            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();

            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
            
return returnValue;
        }
        
public static TReturn Invoke<TContract, TContract2, TContract3, TContract4, TReturn>(TContract proxy, TContract2 proxy2, TContract3 proxy3, TContract4 proxy4, Func<TContract, TContract2, TContract3, TContract4, TReturn> func,  string MethodElapsedTimeText,string MethodErrorText)
        {
            Stopwatch sw 
= new Stopwatch();
            sw.Start();
            TReturn returnValue 
= default(TReturn);
            
try
            {
                returnValue 
= func(proxy, proxy2, proxy3, proxy4);
            }
            
catch (Exception ex)
            {
                
//Handle Exception   
                WebLog.SquareLog.CommonLogger.Error(MethodErrorText + ex.ToString());

            }
            sw.Stop();
            WebLog.SquareLog.CommonLogger.Error(MethodElapsedTimeText  
+ sw.ElapsedMilliseconds.ToString() + "毫秒");
            
return returnValue;
        }
    }

客戶端調(diào)用:

string ComputationTimeText = "取酒店是否在積分廣場(chǎng)首頁(yè)推薦數(shù)據(jù)耗時(shí):";
            
string ErrorMethodText = "取酒店是否在積分廣場(chǎng)首頁(yè)推薦數(shù)據(jù)異常:";
            
string conn = WebConfig.DaoConfig.MisMasterDBReadConnectionString;
            HotelRecommendInfo 
= ErrorAndComputationTimeHandler.Invoke<HotelRequestInfo, string, List<HotelGenericInfo>>(requestInfo, conn, SearchRecommendHotelData, ComputationTimeText, ErrorMethodText);
 

AOP的優(yōu)勢(shì):

(1)上述應(yīng)用范例在沒有使用AOP情況下,也能解決,但是,AOP可以讓我們從一個(gè)更高的抽象概念來理解軟件系統(tǒng)。可以這么說:因?yàn)槭褂肁OP結(jié)構(gòu),對(duì)于一個(gè)大型復(fù)雜系統(tǒng)來說可以簡(jiǎn)化不少代碼。

(2)并不是所有的人都需要關(guān)心AOP,使得其它開發(fā)人員有更多精力去關(guān)注自己的業(yè)務(wù)邏輯。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 盈江县| 洪洞县| 南康市| 图们市| 禄丰县| 青浦区| 邮箱| 阿图什市| 宁都县| 惠东县| 信宜市| 镇原县| 中卫市| 中方县| 义乌市| 岳阳市| 昂仁县| 栾城县| 德庆县| 保山市| 金华市| 洛隆县| 乌拉特中旗| 勐海县| 汉沽区| 吴江市| 三台县| 天水市| 湖南省| 金昌市| 淳化县| 建湖县| 鄂尔多斯市| 宜都市| 佛冈县| 阿城市| 杨浦区| 宜都市| 大理市| 耿马| 蓬溪县|