国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 陕西省| 桑日县| 外汇| 濮阳县| 北安市| 卢龙县| 东莞市| 正蓝旗| 和政县| 西盟| 辰溪县| 昌吉市| 湄潭县| 同德县| 江都市| 阜新市| 宁武县| 乐至县| 绥滨县| 嘉峪关市| 广元市| 怀安县| 德化县| 丰都县| 麻江县| 昌宁县| 庆云县| 靖宇县| 信丰县| 汝州市| 枝江市| 洪湖市| 育儿| 莎车县| 汝南县| 垣曲县| 广灵县| 南京市| 连城县| 莲花县| 荣成市|