小议传统分层与新式分层,抑或与DDD分层

简介:

本文提到的分层只是软件架构上的分层。文中的传统分层指的是传统的三层结构:UI(界面表现层),BLL(业务逻辑层),DAL(数据访问层)。文中提出的观点也都是个人的一点认识,与任何组织没有关系,如有异议,还请各位踊跃拍砖。

当然了,出现的这些问题,也可能只是我个人的问题,不代表每个人都存在。无则加勉,有则改正吧。如果是个人的问题,那就当是个人总结吧,大家看看就算了。

这里说到的传统分层,也有可能是我对于分层的错误理解造成的,但是我看见的不只是我的项目是这么的结构,很多的项目也都是这样的结构。里面的代码, 都和我理解的一样,至少可以说明,还是有一部分人犯了和我一样的错误。

 

传统分层

 

传统分层最大的问题就在于割裂了上层与下层之间的联系,把他们之间的关系变成了简单的接口调用,变成了完全的接口形式主义。同时,忽略了下层是为上层提供服务的,不是单独存在的,下层提供的服务应该受到上层的规约。当然,也不是说不可以提供更多的服务,但是至少应该提供上层需要的,然后再考虑提供一些“边角料”。

我们先看一个传统分层的解决方案结构。

image

相互之间的引用关系是:UI引用BLL、Entity、Common;BLL引用IDAL、Entity、Common;IDAL引用Entity;DAL引用IDAL、Entity、Common。

显示行号 复制代码  UI  Code
  1. private void button1_Click(object sender, EventArgs e)
  2. {
  3. _02_BLL.OrderBll orderBll = Common.ServiceLocator.LoadService<_02_BLL.OrderBll>();
  4. orderBll.SubmitOrder(new _05_Entity.OrderEntity()
  5. {
  6. OrderSeqNo = "123",
  7. OrderAmount = 1000
  8. });
  9. }
  10.  
显示行号 复制代码  BLL Code
  1. public class OrderBll
  2. {
  3. IOrderDal _orderDal;
  4. public OrderBll()
  5. {
  6. _orderDal = Common.ServiceLocator.LoadService<_03_IDAL.IOrderDal>();
  7. }
  8. public bool SubmitOrder(OrderEntity order)
  9. {
  10. return _orderDal.Add(order);
  11. }
  12. }
  13.  
显示行号 复制代码  IDAL Code
  1. public interface IOrderDal
  2. {
  3. bool Add(OrderEntity order);
  4. }
  5.  

 

显示行号 复制代码  DAL Code
  1. public class OrderDal:_03_IDAL.IOrderDal
  2. {
  3.  
  4. public bool Add(_05_Entity.OrderEntity order)
  5. {
  6. IDbConnection conn = new SqlConnection();
  7. conn.Open();
  8. IDbCommand comm = conn.CreateCommand();
  9. IDbDataParameter param = comm.CreateParameter();
  10. param.Direction = ParameterDirection.Input;
  11. param.DbType = DbType.String;
  12. param.ParameterName = "OrderSeqNo";
  13.  
  14. if (comm.ExecuteNonQuery() &gt; 0)
  15. return true;
  16. else
  17. return false;
  18. }
  19. }
  20.  
显示行号 复制代码  Unity Container Locator
  1. using System.Configuration;
  2. using System.Globalization;
  3. using Microsoft.Practices.Unity;
  4. using Microsoft.Practices.Unity.Configuration;
  5. using Microsoft.Practices.Unity.InterceptionExtension;
  6. using System.Web;
  7. using System;
  8.  
  9. namespace Common
  10. {
  11. public static class ServiceLocator
  12. {
  13. // private static readonly InterfaceInterceptor injector = new InterfaceInterceptor ();
  14.  
  15. private static readonly TransparentProxyInterceptor injector = new TransparentProxyInterceptor();
  16.  
  17. public static IUnityContainer Container
  18. {
  19. get;
  20. private set;
  21. }
  22. static ServiceLocator()
  23. {
  24. Container = new UnityContainer();
  25. UnityConfigurationSection unitySection = ConfigurationManager.GetSection("unity"as UnityConfigurationSection;
  26. if (unitySection == null)
  27. {
  28. throw new ConfigurationErrorsException(string.Format(CultureInfo.CurrentCulture, "missing unity configuration section"));
  29. }
  30. Container.AddNewExtension<Interception>();
  31.  
  32. unitySection.Configure(Container, "Container");
  33.  
  34. }
  35. /// <summary>
  36. /// 没?有D为a映3射?指?定¨别e名?
  37. /// name属?性?没?有D赋3值μ
  38. /// </summary>
  39. /// <typeparam name="T"></typeparam>
  40. /// <returns></returns>
  41. public static T LoadService<T>()
  42. {
  43. Container.Configure<Interception>().SetDefaultInterceptorFor<T>(injector);
  44. return Container.Resolve<T>();
  45. }
  46. /// <summary>
  47. /// 为a映3射?指?定¨别e名?
  48. /// name属?性?赋3值μ
  49. /// </summary>
  50. /// <typeparam name="T"></typeparam>
  51. /// <param name="serviceName"></param>
  52. /// <returns></returns>
  53. public static T LoadService<T>(string serviceName)
  54. {
  55. Container.Configure<Interception>().SetDefaultInterceptorFor<T>(injector);
  56. return Container.Resolve<T>(serviceName);
  57. }
  58. }
  59. }
  60.  
  61.  

上层在调用下层的时候,不是调用自己需要的,而是从下层提供的服务中筛选一些可以用的,凑合用一下。如果发现没有自己可以用的,就在IDAL文件中添加一个,然后在DAL文件中实现以下,这下好了,BLL可以用了。这样也会造成在开发DAL层的时候,没有充分考虑BLL的需要,自己盲目实现一些,然后BLL用的时候,才发现很多还要重新写。造成大量的浪费,代码、人力、时间、精力都浪费一部分了。也会影响到开发的进度。

 

新式分层,抑或叫做DDD分层

 

说是新式分层,其实也是我随便叫的。就是这段时间看了博客园的一些DDD文章,还有就是codeplex上的两个项目NLayerApp和SmartCA的源码。看了这些之后,有的一点理解。不管是神似还是形似吧,反正觉得比以前传统分层有一点道理,就分享出来了,也挣点人气,骗点点击量,哈哈。

先来一张图吧。

image

DDD中的分层主要是四层:Presentation(表现层),Application(应用层),Domain(领域层),Infrastructure(基础层)。

Presentation相当于以前的UI层。Application是一个任务的调度层,没有实际的业务逻辑,也不推荐放入业务逻辑,实际中可以用Wcf来代替,或者使用普通的类库就可以。其实就是根据UI的业务调用,然后映射到具体的领域对象身上去。也可以通过Application来暴露粗粒度的业务处理,因为领域层的业务处理是细粒度的。没有了以前的DAL,把它的部分放入了Infrastructure层。

以前的IDAL被放入了Domain,在图上,是Domain.Core项目,这个项目会被Infrastructure引用。因为Domain.Core中的IDAL相当于是领域对象对于持久化提出的要求,也就是说必须要实现这些功能,这些都是领域对象需要的。具体的如何实现,具体如何持久化,是持久化到关系数据库还是文件系统,还是内存数据库,都由具体的实现来定义。也就是图中的Infrastructure.Data.Core和Infrastructure.Data.MainModule项目。这两个项目中的实现,实现的都是领域对象持久化所需要的,不会实现一大丢不必要的方法。不知道这算不算是改进呢?

 

结论

传统分层,或者说是我理解的传统分层,存在的问题就是割裂层之间的联系,形式化了层之间的联系。没有表达出上层对于下层的需要,下层是为上层服务的,这些联系。DDD的分层可以解决这个问题,会提高开发的效率,少走一些弯路。

不知道大家是如何认识的呢????????期待大家的回复,拍砖。

Technorati 标签:  DDD, NLayer, 分层



本文转自 virusswb 51CTO博客,原文链接:http://blog.51cto.com/virusswb/475728,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
架构师 测试技术 Linux
嵌入式软件架构中抽象层设计方法
嵌入式软件架构中抽象层设计方法
43 0
|
设计模式 JSON 架构师
你真的需要防腐层吗?DDD 系统间的7种关系梳理与实践
当提到系统间交互的时候,人们都会想到大名鼎鼎的防腐层,用来防止其他系统的模型变更对本系统造成影响。但是在实践这个模式的过程中,我们常常会遇到问题。此时我们也应该考虑下其他的系统交互方式。
26276 12
你真的需要防腐层吗?DDD 系统间的7种关系梳理与实践
|
缓存 前端开发 中间件
DDD 领域驱动设计落地实践系列:工程结构分层设计
前面几篇文章中,笔者给大家阐述了 DDD 领域驱动设计的三大过程,重点围绕如何通过战略设计与战术设计进行 DDD 落地实践进行了详细的讨论,但是还没有涉及到工程层面的落地。实际上所有的这些架构理论到最后都是为了使得我们代码结构更加清晰,从而开发出 bug 少、扩展性强、逻辑清楚的应用。因此本文就是为了解决 DDD 领域驱动落地实践最后一公里问题,将我们分析出来的领域模型通过与工程结构的映射实现真正的落地。
DDD 领域驱动设计落地实践系列:工程结构分层设计
|
2月前
|
消息中间件 前端开发 测试技术
DDD - 分层架构:有效降低层与层之间的依赖
DDD - 分层架构:有效降低层与层之间的依赖
|
9月前
|
存储 缓存 前端开发
漫谈分层架构:为什么要进行架构分层?
为什么要分层 高内聚:分层的设计可以简化系统设计,让不同的层专注做某一模块的事 低耦合:层与层之间通过接口或API来交互,依赖方不用知道被依赖方的细节 复用:分层之后可以做到很高的复用 扩展性:分层架构可以让我们更容易做横向扩展 如果系统没有分层,当业务规模增加或流量增大时我们只能针对整体系统来做扩展。分层之后可以很方便的把一些模块抽离出来,独立成一个系统。
|
10月前
|
消息中间件 缓存 前端开发
新项目,不妨采用这种架构分层,很优雅!
新项目,不妨采用这种架构分层,很优雅!
160 0
|
11月前
|
芯片
驱动设计思想_面向对象_分层_分离
驱动设计思想_面向对象_分层_分离
82 0
|
JSON 缓存 监控
代码分层设计
在搭建一个项目之前,除了要进行架构和业务方面的设计和分析,往往还需要对代码的结构进行规范化设计。而分层思想,是应用系统最常见的一种架构模式。
435 0
|
缓存 Oracle 安全
优秀的代码都是这样分层的?
优秀的代码都是这样分层的?
125 0
优秀的代码都是这样分层的?
|
消息中间件 Dubbo 前端开发
分层架构
最近连续做了两个新项目,借着新项目的机会,重新审视一下之前一些实践方法,进而寻求一下背后的理论支撑 新项目开始,首先一个就是会新建一个project,那么这个project怎么分层,怎么创建module,怎么分包呢?
185 0
分层架构