一个不必要的设计

     这个不必要的设计应该说是当前时期的不必要设计更加准确一些。

     10月份进了新公司,先了解业务,同时开始做技术架构,现在刚写完概要设计。这是一个全新的项目,在我来之前,只进行过需求的分析,分析文档已经很全面了。总得来说,这是一个需要面对业务扩展的项目的,因为项目二期、三期的扩张主要是业务上的扩张。

     做的技术架构从整体上讲是一个三层架构(也可以称为4层),前端表现层(表现+业务组织),中间是BLL,后面是DAL。为了应对业务的扩张,BLL层与表现层完全分离,通过接口和概念模型进行交互。完全通过接口来进行交互的另外一个原因是BLL对外提供的服务封装成了Remoting服务。假如,每次增加一个接口而增加一个tcp://...:9999/uri这样的地址映射的话,无疑也是很麻烦。于是在Remoting服务端包装了一个工厂。

     IRemoteFactory factory = BLLFactory.GetRemoteFactory();

     IUser user = factory.CreateInstance<IUser>("UserImpl");

     考虑到CreateInstance是个字符串不能比较难于管理,因此增加了一个枚举型

     enum BusinessImplEnum : int

    { UserImpl }

    于是RemoteFactory就变成了 IUser user = factory.CreateInstance<IUser>(BusinessImplEnum.UserImpl );

    现在增加一组业务实现,只需要定义一个接口,然后实现该业务接口,再把该实现注册到BusinessImplEnum枚举里就行了。

     这个设计似乎很好了,对外访问的API一致,可以在BLLFactory增加路由功能,在后端集群Remoting服务。但这是个新业务,照我的估计1~2年内不太可能需要扩张到那种程度。而为了在开发期间不会涉及到两个进程以上的测试,在BLLFactory增加了非Remoting通道,也就是说,开发版本的BLLFactory是对BLL依赖的。

     这样,这里的设计就会感觉比较复杂,用了2次反射(Debug版本是1次反射,而Release版本就是两次,一次是远程Remoting的调用,一次是对业务实现类的反射)。现在想来,完全没必要搞那么复杂,完全可以不做设计,而尽可能快地完成第一个版本的开发。让表现层依赖于业务层并没有什么大的问题,并不是使用了工厂扩展性就好了。确实,使用了工厂有一步到位的感觉,但是确实给组员造成了一定的困惑。一步实现这种方式,并不是所有人都能一下子理解这个结构的意图。

     而做这个架构,我原本的意图是领域驱动开发,而这种架构不光是领域驱动,还带有了一部分技术驱动的成分。如果没有接触过Remoting的人,就不知道为什么业务实现类必须继承自MarshalByRefObject类,为什么不能使用抽象类。不熟悉这部分的人,不得不花额外的时间去学习这个技术,从而影响到概要设计进度。

    这里完全可以不做设计,或者说不做这么复杂的设计。为了实现表现层与业务层的解耦,完全可以对业务层进行包装,以大家都能理解的方式进行包装。比如只使用工厂,而不使用Remoting。还可以用简单工厂替换掉抽象工厂,虽然增加了工厂代码,但是把简单工厂转换到抽象工厂还是很容易的。从而在当前时期,把关注点始终放在对业务的理解上。

posted @ 2009-10-26 22:16 Birdshover 阅读(...) 评论(...) 编辑 收藏