数据层采用PO(Persistence Object),做为数据的基本载体。由于采用了Hibernate,因此PO与PO的关联都采用对象直接关联的方式,而不是用只关联对象GUID的方式。是否采用 Lazy Load 模式,还有待再次的实践。
数据持久化采用DAO(Data Access Object),由于使用了Hibernate,因此对于单个对象的增删改查几乎不需要做任何的操作,对于每个具体的业务,也要写相应的DAO,主要是用于复杂查询和统计。
业务层采用BO(Business Object),做为业务逻辑的基本载体。BO主要是PO业务逻辑的包装,也就是说BO继承PO(我这次就是这么实现的,但感觉不如后一种方式好),或者BO委托(delegate)PO,同时包含对于此PO的各种业务操作(业务逻辑和持久化)。PO一定会对应一个BO,但是BO并不一定会对应于PO,有些BO可能是纯粹逻辑的,并不需要持久化。BO中的业务操作,都是BO单体自身可以主动发出的业务动作。
业务层我新采用了一个BC(Business Container)的概念,业务容器。这个容器,包括业务逻辑的上下文(用户名,环境属性设置等),同时每个具体的业务容器,也负责对相对应的具体BO集合,进行统计和查询工作。也就是说BO只是对业务单体进行操作,而BC则负责对整个BO集合进行操作。所有的查询统计,都是由BC完成的。同样,BC与BO也不是完全对应的关系,有些BC也是纯粹逻辑上的,没有相对应的BO。
UI采用的是Struts技术,因此UI逻辑都写在了Action里面,主要是负责准备数据,接收数据和拼装界面的。ActionForm相当于一个个的UI组件(表单组件),因此它不应该只是一个简单数据的载体,此次我将BO委托于ActionForm之内,ActionForm所有的方法,都是代理BO的方法,同时BO<->Form之间的转换逻辑,也都直接写在了代理方法之内。这样 ActionForm 就成为了一个UI的表单组件。
对于每个业务对象单独的操作(增删改查),我将其放置于一个Action之内,而对于业务对象的查询(复杂查询和简单列表等涉及到多个业务对象的操作),我将其另放在一个QueryAction之内。因为本身,这两个Action对应的Form就是完全不同的。Action对应的是Form被BO所委托的,而QueryAction对应的则是与查询条件相关的Form。
上段的最后一句话,“与查询条件相关的Form”,我想实际上也就是我下一段工作的重点。再上面提到的Form分成了两种,一种是MaintenanceForm,用与对象的增删改查的基础操作,它被BO所委托;而另一种则是QueryForm,它应该是被QueryObject(假设它存在的话)所委托的,而QueryObject应该是与BC相对应或关联的。QueryObject在QueryForm中被填充,在BC中继续处理(可能是添加上下文环境等)并执行,然后将结果返回给BC。QueryObject被BC执行,实际上也就是被传进了DAO层,根据QueryObject所包含的各种属性参数,生成相对应的查询语句,并将结果返回。QueryObject我个人认为,是个很有趣的东西,值得以后在应用实践中好好研究。
下面的一段摘自我的工作日志:
03.29
重构了协同办公引擎的整个代码,在WEB层和DAO层之间,加入了BIZ层,结果令人惊奇,减少了三分之一的冗余代码。在重构过程中,对BIZ层的作用,有了比较深刻的认识,和我以前理解的概念是相同的,业务逻辑层,相当于命令行的接口。另外,关于BO、PO、POJO有了重新的认识,至少以前对BO的概念理解上,不是完全正确的。BO是在业务层BIZ中存在的,而PO则应该在DAO层中存在的。
04.07
虽然是完成了,但是代码却是丑陋的,充斥了重复和不规则的代码,无论是维护还是修改都不容易。结构和效率上也存在着相当的问题,总之,如果从代码的角度来看,我认为,这些大部分都是垃圾。还需要重构。另外,由于没有单元测试,每一次我修改和增加功能的时候都比较的拘束,无法放开手脚,希望以后能够逐渐改进。
04.21
非常顺利的重构完了所有的代码,开始添加用户权限过滤的上下文权限。由于重构之后,结构非常好,因此对其非常有信心。
在重构的过程中,有一些意外的发现,用命令模式实现业务逻辑。这样基本就实现了我最初构想的用命令行方式执行的业务核心引擎的构想。还不是很成熟,而且没有实践过,但是是的确可行的,有时间,会做个演示的样例。
04.23
完成了 用户上下文环境 及 分页标签 的添加,由于之前的重构,使得程序的结构非常的优良,因此改动是非常的有信心,而且也非常的容易,几乎没有什么大问题。
体验到了重构的快乐,并且在修改中感觉到了重构的威力。再接再厉!
重构了一天的代码,并且思考了许多相关的问题。结果是卓有成效的,令人满意。希望这些能为以后的代码自动生成,奠下良好的基础。
代码自动生成的基础,我个人认为,是要有良好的系统结构,和层次分明的代码体系(这些是需要经验积累的,也是需要人先写出来,并实践过的)。生成的代码,人手工不需要也不应该对其进行更改,手工代码是以继承或关联的方式来使用这些生成的代码的。
代码生成,我想最多也就能解决项目中20%-30%的问题,不多,不过我想这些足够了。程序员应该做为技术人员和工匠更关注于真正的业务逻辑,而不应该象工人一样,不断地为一些基础的繁琐的大致都一样的东西而心烦。
代码生成工具,就像是盖房子用的脚手架,没有通用的。每次盖房子的时候,脚手架都要重新搭建,房子盖好了,脚手架也就要拆了。代码生成器,和其它类似的项目辅助开发工具,也象脚手架一样,用的时候重写或重用,项目结束后,就废弃掉。也许你会认为这些需要花大量的项目资源和成本,但我认为,一旦这些成为习惯或为人理解熟悉之后,这些东西,都是很快就可以构造出来的,根本不需要多少的资源和成本。不知道你见没见过工人搭脚手架,实在太快了,在我这样的外行人看来,快得都有些不可思议。
代码生成不是银弹,最关键的,我想还是程序员自己。
CVS的分支合并策略有些问题,主支与分支合并的时候,非常的容易出错,常常是一片飘红(冲突),让人不知所措。想了半个下午,又重新看了 ClearCase 的文档,终于,有些了突破,不过还是存在一些问题。
分支合并的一些想法:
1. 在 ClearCase UCM 中,存在着 基线、组件、流、变基 这些的基础概念,CVS 通过 分支 和 标签 可以模拟实现出大部分,除了 组件和变基 。因此,在当进行对组件变基这个操作的时候(将主支中的一部分稳定的基线,合并至当前工作的分支),显的非常麻烦,甚至有些无可奈何。虽然,通过用手工的给某一组的文件打标签来实现组件,通过合并主支上的某一标签来实现变基,但这样做对管理员的负担,实在是比较大。希望以后能找到一些合适的办法。
2. 另外,还有一点,目前向CVS库中提交的时候(尤其是使用Eclipse做为客户端),许多 JSP、TLD 、CSS 等文本文件,被当做二进制文件,提交进CVS。在比较和合并的时候,非常非常的麻烦,因为不知道两个文件的差异。这一点,一定要注意,并在以后加以改正。
将近断了一周的网络,今天终于恢复了,偶也就顺便注册了这个Blog,以示庆祝。另外,对Blog的模板,进行了一下个性化的处理,看起来感觉还可以。
再过两天就要回家过年了,真是什么都不想干了。
共1页 1


