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; } } }