在标准用户体系的开发中,我和jacty就开发架构的问题进行了长时间的争论。
在长达一天的争论中,我们逐渐明白了传统的三层开发、ORM和DB4O的区别。
1。在以往的项目中,我们抽象出各个实体。并按照面向对象的原则给这些实体赋予一定的属性和方法。这些实体,加上一些Tool类构成了业务逻辑层。我们的底层是一个类似于sqlHelper的类。顶层则是页面。
2。对以上的改进:在实践中,我们发现几乎所有的实体层都有三个基本的方法:增、删、改、查。这样,我们建立了一个虚类:Substance。然后各个实体都继承自Substance。Substance完成了基本的动作:增、删、改。
这样各个子类只需要将自己的属性和额外的方法即可。大大提高了编写效率。这样,我们构成了四层的模式。
3。在进一步的探索中,我们发现:实体类和Substance中对数据的操作都有一个特点--对单表的操作。于是出现了Substance和底层的一个中间层:SinggleTable,进行了对单表的包装,使之更利于排序、分页等。这样,我哦马成为了一个“四层结构”。
4。在参阅了微软提出的petShop后,我们发现,将实体作为一个Model是一个更好的方法。这样可以把动作定义为一个接口,从而利用工厂模式适应不同的底层。于是,我们觉得标准用户体系用这样的方法开发。
5。在对petShop 的深入研究中,我们发现,其实PetShop并不是完全的面向对象。它只是一种“输出的面向对象”,而非“输入、输出的面向对象”。因为在PetShop的BLL层,返回类型都是Model层定义的实体;甚至返回多条记录的时候,也没有使用传统的DataSet,而使用了IList的泛型。它的输出确实面向对象。但是他的输入呢?比如要增加一个Order,可以传一个OrderInfo(order的实体)进入,这是面向对象的。但是检索符合特定条件的Order的IList的时候呢?它要求传入相干的条件。而按照OO的思想,应该是传入一个OrderInfo的实例作为样本查询。而且,petshop的Model层,所有的实体属性都是用的值类型。但是根据面向对象的思想,在有外键的地方,应该设计为其他对象的一个实例作为属性。如现在有两个类:Order和Product。一个order里面含有一个Product,那这个时候,Order的一个属性就应该是 ProductInfo型的,而不是一个string型的productID。
另外,petShop也出现了许多重复代码。如在SQLServerDAL 层(即具体实现功能的层,位于.“NET Pet Shop 4.0\SQLServer”)中,代码大部分和Oracle相关实现重复。
对于解决以上的问题,我们展开了激烈的讨论。尤其是对于第三个问题,我们都提出了一些解决方案。如具体实现的时候,微软为什么要写这么多重复的代码?无非就是因为对数据的操作和对业务逻辑的操作没有分开。业务逻辑可以理解为“当做某个事件的时候,需要先得到那些信息,然后新型哪些数据或者非数据的操作”,而数据操作则指打开数据持久层,进行数据的读取和写入。微软的BLL层正是无法分开逻辑操作和数据操作,所以就造成了代码的重复。因此我们致力于这个方面。
但是经过一天的讨论,我们最后不得不沮丧的发现。如果解决这个问题,并且让我们的系统无缝的适应新型的数据库或者DB4O、NH等等,我们不得不自己对ACCESS和SQLServer实现一个ORM,我们对数据的操作就应该类似于使用DB4O的时候对数据的操作!这样做的难度不低于开发一套DB4O,然后还要开发一套标标转的面向对象数据查询语言。
目前DB4O在面向对象的查询语言方面取得了一定的进展,但是面向对象的查询语言有着先天的弱点,以至于现在DB4O不能广泛的被利用。理想的面向对象的查选语言应该是根据一个样本进行查询、更新等操作。但是在查询的时候,到底哪些字段要匹配,哪些不要匹配呢?DB4O中规定,在进行int型的查找时,传入的样本的int型属性为0值的时候不予作为匹配条件,字符串为空的时候不予作为匹配条件。。。但是问题在于,假设说我就是想查出0值的怎么办?假设说我就是想查出空值的怎么办?
因此,最后我们发现,这一系列的问题,根本不是我们的能力可以解决的。
但是最后,总要形成一个解决方案。我们讨论决定。输入输出都面向对象的方法。但是在BLL层的具体操作还是象微软的PetShop一样。