在今天的.NET世界中,微软所发布的那些经典例子Duwamish和Petshop所采取的那种N层的模式已经深入人心。其实不管这些例子采取多少层,基本上都可以归结为最基本的三层,也就是微软的三层架构,简单点就是下面的图:
UI layer
↓
Business layer
↓
DataAccess layer
↓
Database
网上关于此类东西的讨论的文章不在少数,成功的项目也不在少数。但这里我要说一说我自己觉得的几个问题(可能是因为我水平不高吧):
1) 采取此种做法,如果系统已经开发完成,但需要增加一些新功能,可能会觉得很难添加,因为可能会修改已有的表的字段。
2) 所谓的business layer,里面封装了很多只是起一个转发作用的代码。最明显的莫过于一些(new XXXAccess()).ReadAll(),然后转给了DataAccess执行。
3) 如果我们要对business layer做单元测试,会发现如果没有数据库或者数据库没数据我们需要写上一堆的mock对象。
4) 基本上对于每张数据库表就需要有一个DataAccess,然而有时候会有一些业务对象的处理要同时取好几张表的数据,这个时候就不知道这个方法我们应该放在哪。
这些问题时常让我觉得困惑,尽管在开发中使用一些模式能够解决掉一部分问题,但是总觉得并没有从根本上解决上面的一些问题。
-----------------
经过一段时间的探索以及对一些Java资料的参考,终于想明白解决上面问题的办法的一种方式是进行面向对象的建模。分层的思想同样是适用的,如果我们直接套用上面的那些名称的话,这种关系就变为(*):
UI layer
↓
Business layer
↑
DataAccess layer
采取这种方式,那么上面的几个问题就迎刃而解了:
1) 我们为什么用OO?不就是为了适应变化吗?
2) business layer现在成为了整个系统的核心,虽然仍可能会有一些这样的代码,但是含义上却是不同的。
3) 这个时候可以脱离数据库进行单元测试,因为你开始根本不会取管DataAccess layer。
4) 这个问题现在归结到类的设计的问题。
(*)注:为了简单就直接这样表达了,其实真正想表达的东西来自《Domain Driven Design》的分层,有兴趣的朋友可以去翻翻。
----------------
当然,这种方法并不是银弹,它也有着自身存在的一些问题:
1) 繁琐。相对于非常直观的三层架构,这种方法需要更好的OO思想和经验,对开发人员的要求也更高。
2) Business layer和DataAccess layer会形成一个双向依赖,需要用依赖注入或者其他方法来解决这个问题。
3) .NET目前仍然缺乏足够好框架来支持对象的持久化。(或者可以等Linq?)
4) 依这种方法得到的数据库表会比较晦涩,不太适合做OLAP。
当然,写这篇文章的目的是起一个抛砖引玉的作用,让大家可以从一个不同的角度去思考问题,并不是说明下面的就一定比上面的要好。
PS:晚上跟一个很厉害的老外聊天说Hibernate对java来说也是个crap,会导致很多问题。我知道这里有做过java的朋友,能否指教一下是不是这样?