技术讨论总结:客户化、缓存
最近,GIX4项目需要开展客户化工作。同时,下一期sprint中,客户还要求大幅度提升产品的性能。针对所存在的问题,开发人员决定开一系列的技术讨论会。
我总结了目前遇到的和可能遇到的问题:
客户化:
实体类客户化
各客户对同一产品表现出的需求,要求实体类在一定程序上各不相同。这就需要领域模型做到可以客户化。
界面客户化
需求不同,界面自然也需要客户化。这是一般性需求。
性能:
实体类优化
目前系统使用的是基于CSLA对象模型的实体类。由于使用了CSLA托管属性,性能比较差。同时,由于一个聚合类往往通过多个多层的实体类聚合而成,调试时却都是在调试CSLA的基类,基类中为所有实体类使用同一种模式进行架构,而用递归和继承来实体类间结构,使得代码难于调试,经常让人晕头转向。
缓存的植入
要提升现在分布式系统的性能,最直接最易用的方法就是对一些常用而不常变的对象进行缓存,减少网络传输,减少数据库访问次数。
20100826
今天和周哥、杜强、智哥一起讨论了系统的客户化方案。时间持续了大概2个小时,内容不多,收获也不多,但是觉得很重要。主要有以下两点:
第一、更加清晰了GIX4(包括OpenExpressApp)的思想、架构和RoadMap。
我想,产品GIX4架构思想可以这么解释:特定于建筑领域的产品线架构方法。
产品不同于项目,它是为整个建筑行业开发的,需要考虑其通用性,同时也必须能够满足各企业的定制化需求。整个产品线开发中,包含了三类客户,按照721的原则划分,这三类客户是:
一类用户:70%;这些客户的功能需求完全符合整个行业的习惯,他们代表了行业的一般性情况。这些需求肯定要被包含在产品中。
二类用户:20%;这些客户一般分为几种类别;同一类客户的需求往往相同,同不类客户的需求往往不同;这些需求一样要被包含在产品中,产品需要一定的策略来给各类用户进行定制。
个性用户:10%;这些客户的功能需求往往源自其自身的习惯,往往不能被其它同行所采用。这类需求将不会被包含在产品中,但是作为一个有平台性质的产品,应该具备为这些用户定制功能的扩展能力。
软件架构采用领域驱动,所以主干代码中的领域模型需要代表行业的整体需求。同时,也要能表达二类用户的情况,这可能需要多个小分支模型。个性用户的需求需要在主干模型的基础上扩展。(在类设计上主要使用继承,而建模环境将会在不远的将来支持,同样也需要支持模型扩展。)
第二、设计时,应该尽量避免二义性。
关于设计的讨论,是在讨论一个具体的问题引起的小插曲,问题如下:
在原来的产品设计中,有这样的聚合关系:Project->Contract->Budget;但是现在需要同时支持:Project->Budget。而这两个需求本身就是从两家不相干的客户提出,它们不能同时存在。
我一开始主张BudgetParent->Budget的聚合,然后Project和Contract都继承自BudgetParent。提出这个方案的原因在于,我从客户的需求开始倒推领域需求,我觉得在客户的浅意识里,Budget之上是有某一个东西有进行组织(BudgetParent)。但是后来知道,这个推论是片面的,行业内并没有这样的认知。所以从领域角度讲,这个设计并不成立。
对于我提出的方案,周哥提出尽量不要带有二义性的设计。如果只可能是Project和Contract,在没有必要的情况下,不需要再引入一个“BudgetParent”类或接口。这样不但会增加程序的复杂度,更重要的是它会让程序变得含糊,看程序的人并不能从类的设计上一眼看出领域需求。后来一想,确实如此,没有必要的话,还是使用具体类再加有实在意义;不要因为程序的考虑,而使得领域复杂化。
后来的结论是:需要再次和领域专家确认后,才能知道到底一个Budget会不会可能同时被Project和Contract进行组织。如果是,则Budget类本身应该拥有Project和Contract的引用。如果不是,则可能需要设计两个不同的Budget子类来实现。确实,不管最后是选用哪一种,都能清晰地表达出Budget、Project、Contract之间的关系。:)