Service模式介紹
領域中的一些概念不太適合建模為對象,即歸類到實體對象或值對象,因為它們本質上就是一些操作,一些動作,而不是事物。這些操作或動作往往會涉及到多個領域對象,並且需要協調這些領域對象共同完成這個操作或動作。如果強行將這些操作職責分配給任何一個對象,則被分配的對象就是承擔一些不該承擔的職責,從而會導致對象的職責不明確很混亂。但是基於類的面向對象語言規定任何屬性或行為都必須放在對象里面。
所以我們需要尋找一種新的模式來表示這種跨多個對象的操作,DDD認為服務是一個很自然的范式用來對應這種跨多個對象的操作,所以就有了領域服務這個模式。
領域服務職責
- 領域服務沒有狀態只有行為
- 領域服務是無狀態的
- 避免領域邏輯泄露到應用層
- 領域服務具有Façade的功能
說到領域服務,還需要提一下軟件中一般有三種服務:應用層服務、領域服務、基礎服務。
LCLFramework框架之Service設計
LCLFramework框架之Service模式設計代碼
public interface IDomainService { void Invoke(); } public abstract class DomainService : IDomainService { protected abstract void Execute(); public void Invoke() { this.Execute(context); } } /// <summary> /// 服務命名規范: /// 1:服務名稱Service /// 2:服務名稱Service_V10002 /// </summary> [DebuggerDisplay("Count = {Count}")] public class DomainServiceLocator { public static readonly ServiceLocator Instance = new ServiceLocator(); /// <summary> /// 內存保存的服務名稱規范 /// 1:服務名稱 /// 2:服務名稱_V10002 /// </summary> private static Dictionary<string, Service> _allServices = new Dictionary<string, Service>(100); public ServiceLocator() { } public void TryAssemblyAddServices() { try { Assembly assembly = Assembly.GetExecutingAssembly(); var pluginTypes = assembly.GetTypes().Where(p => p.BaseType == typeof(Service)); foreach (var type in pluginTypes) { TryAddService(type); } } catch { try { _allServices = new Dictionary<string, Service>(100); TryAddService(); } catch (Exception ex) { LogManage.AddErrorLog(ex, "服務初始化錯誤......"); } } } public void TryAddService(Type serviceType) { var ser = Activator.CreateInstance(serviceType, true) as Service; string serviceName = serviceType.Name; serviceName = serviceName.Replace("Service", ""); serviceName = serviceName.ToLower(); _allServices.Add(serviceName, ser); } public Service FindImpl(string contractType) { if (string.IsNullOrWhiteSpace(contractType)) { return null; } Service list = null; if (_allServices.TryGetValue(contractType.ToLower(), out list)) { return list; } return null; } public Service FindImpl(string contractType, string version) { if (string.IsNullOrWhiteSpace(contractType)) { return null; } // 服務名稱_V10002 string sernamever = contractType; if (string.IsNullOrWhiteSpace(version)) { return FindImpl(sernamever); } else { sernamever = contractType.ToLower() + "_V" + version; } Service list = null; if (_allServices.TryGetValue(sernamever, out list)) { return list; } else { // 如果沒有找到當前版本,就還回默認版本。 return FindImpl(sernamever); } } public int Count { get { return _allServices.Count; } } }
LCLFramework框架之Service使用
加載服務:
public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { ServiceLocator.Instance.TryAssemblyAddServices(); } }
創建服務:
public class FrequentService : DomainService { protected override void Execute(System.Web.HttpContext context) { //業務邏輯 } }
調用服務:
public class HttpHandlerDemo: IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; try { string sMothod = LRequest.GetString("method"); string version = LRequest.GetString("version"); if (!string.IsNullOrWhiteSpace(sMothod)) { context.Response.Clear(); var service = ServiceLocator.Instance.FindImpl(sMothod, version); if (service != null) { service.Invoke(context); } else { LogManage.AddActionLog("系統不提供【" + sMothod + "】服務,請檢查輸入. "); } } else { context.Response.Write("系統需要提供服務名稱."); } } catch (Exception ex) { LogManage.AddErrorLog(ex); } } public bool IsReusable { get { return false; } } }