資訊系統日益增多,不同系統常採用不同技術、平台開發,缺乏統一規劃、資料標準與呼叫介面,導致系統交互困難。常見做法是讓開發人員提供 Web Service 或 HTTP 介面,但需求頻繁變更、代碼持續迭代,應用端增加導致資料格式、特殊處理、DTO 設計不斷變動。使用 .NET 的開發者深知:Web Service 更新需同步更新應用端代理類,產生強依賴。首要細節問題:解決服務端與應用端強依賴,設計通用介面規範。
public interface IAOPResult {
int ResultNo { get; } // 回傳代碼:<0 異常,0 成功,>0 提示
string ResultDescription { get; } // 描述訊息
object ResultAttachObject { get; } // 附加資訊(物件/陣列)
IAOPResult InnerAOPResult { get; } // 內部 AOP 結果
bool IsSuccess { get; } // ResultNo == 0
bool IsNotSuccess { get; } // ResultNo != 0
bool IsFailed { get; } // ResultNo < 0
bool IsPassedButFailed { get; } // ResultNo > 0
IAOPResult ThrowErrorOnFailed(); // 失敗時拋出異常
}
[Serializable]
public class AOPResult : IAOPResult { ... }
[WebMethod(Description = "檢查購物車中的禮品")]
[SoapHeader("header")]
public AOPResult CheckGiftForCart(List<CartLineDTO> carlist, bool returnflag) {
ValidateAuthentication();
return (AOPResult)CartGiftCenter.GiftService.CheckGiftForCart(carlist, returnflag);
}
[WebMethod(Description = "獲取所有的贈品信息")]
[SoapHeader("header")]
public AOPResult GetGiftList() {
ValidateAuthentication();
var result = (AOPResult)CartGiftCenter.GiftService.GetModelList();
if (result.IsSuccess) {
result.ResultAttachObject = result.ResultAttachObject.ObjectToJson();
}
return result;
}
[WebMethod(Description = "根據Id獲得組信息")]
[SoapHeader("header")]
public AOPResult GetGroupInfoByID(int Id) {
ValidateAuthentication();
var result = (AOPResult)CartGiftCenter.GroupService.GetModelInfoById(Id);
if (result.IsSuccess) {
var resultobj = result.ResultAttachObject as GiftGroup;
result.ResultAttachObject = new GroupLineDTO {
GroupId = (int)resultobj.GroupId
}.ObjectToJson();
}
return result;
}
所有服務方法採用相同回傳類型 AOPResult,可裝載物件或陣列。物件需序列化為 JSON:
public static class JsonExtensions {
private static JavaScriptSerializer javaScriptSerializer = new JavaScriptSerializer();
public static string ObjectToJson(this object obj) {
return javaScriptSerializer.Serialize(obj);
}
public static T JsonToObject<T>(this string json) {
if (string.IsNullOrEmpty(json)) return default(T);
return javaScriptSerializer.Deserialize<T>(json);
}
}
public class AspectF {
internal Action<Action> Chain = null;
internal Delegate WorkDelegate;
public void Do(Action work) { ... }
public TReturnType Return<TReturnType>(Func<TReturnType> work) { ... }
public static AspectF Define { get { return new AspectF(); } }
public AspectF Combine(Action<Action> newAspectDelegate) { ... }
public static void Retry(int retryDuration, int retryCount, Action<Exception> errorHandler, Action retryFaild, Action work) { ... }
}
public static class AspectExtensions {
public static AspectF Delay(this AspectF aspect, int milliseconds) { ... }
public static AspectF MustBeNonNull(this AspectF aspect, params object[] args) { ... }
public static AspectF MustBeNonDefault<T>(this AspectF aspect, params T[] args) where T : IComparable { ... }
public static AspectF WhenTrue(this AspectF aspect, params Func<bool>[] conditions) { ... }
public static AspectF RunAsync(this AspectF aspect, Action completeCallback) { ... }
public static AspectF RunAsync(this AspectF aspect) { ... }
}
效能開銷:物件序列化/反序列化、強制轉型、傳統 AOP 反射開銷。但一般專案利大於弊。
DTO(Data Transfer Object)用於遠端呼叫大量傳輸物件。例:資料表 20 欄位,PO 物件 20 屬性,但介面僅需 10 欄位,無需傳輸完整 PO,以 10 屬性 DTO 傳輸。
實際場景需考量:
本篇先止於此,歡迎討論。下章探討利用泛型簡化多資料庫操作。