小议解耦合--应用设计模式
一直对设计模式究竟要什么时候用,如何用不是很清楚,但在以前写的代码中的很多地方,我都感觉代码总是写得很怪,很乱,可又不知道怎么去改。最近看了些文章,对设计模式有了些新的理解。
先举个自己做过的例子片段来讲。一个进销存系统中,订单管理要负责管理销售订单,采购订单的处理。下面是这订单的数据模型:(为了考虑简单着想,忽略了很多字段,也没有考虑订单详细子表等)
其中OrderType字段用来区别是销售订单还是采购订单,0为销售订单,1为采购订单。其他字段意义如下:OrderDate—下单日期,TotalMoney—订单金额,dealer—经办人。
先说说我以前的做法:
因此,就构造如下的处理模型:
代码片段如下:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
每次看到这里,我就有一种说不出来的奇怪感觉,总觉得哪里不对劲,昨天看了一篇文章后,我终于想到了什么不对了。因为有两种订单要处理,因此需要在新增订单的时候对订单进行判断。可如果日后订单的类型越来越多,那么业务逻辑层的if/else代码就会越来越多,那么代码的耦合度程度就越来越高了,若一处代码发生了错误,则定位错误和修改bug就十分头痛了。我想本质原因还是因为没有把三层架构的核心思想理解透,中间的业务逻辑层本来就是用来作为用户界面层和数据访问层的一个“隔离带”,作为一个业务接口的。可我在这却是反其道而行,违背了“接口要简单”这个原则,提供的接口过于复杂,接口内部耦合度过高,因此需要进行解耦合。
下面是我对这个问题解耦合的一个思路,通过策略模式(Strategy)来解决:
通过抽象类Order中提供一个抽象方法InserNewOrder(),然后在两个子类中分别实现这个抽象方法,这样就可以再通过一个工厂方法来处理上面这个问题了,代码片段如下:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
![](/Images/OutliningIndicators/ExpandedBlockEnd.gif)
![](/Images/OutliningIndicators/None.gif)
这样在用户界面层处理代码中,就可以如下处理了:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
这样做的好处就是若有新的订单类型加进来,那么就只需要新增一个Order类的子类就可以了,而不用去修改用户界面层的代码,这样就把变化限制在一个地方了,这样对bug的修改也方便了,不会到处都是混乱的代码,业务逻辑层也不会过度膨胀。
更进一步,我还有如下的想法,不过不知道合适不合适,我的想法是,数据库里的数据实体表应该对应一个数据实体类,针对这个实体类的处理应该由这个实体类完成,这样就符合“类的责任自我实现”这个原则,因此我的设想的架构如下:
但我还是有一个疑问弄不清楚,象这里我如果采用后面这两种代码架构的方式的话,那么就引入了额外的类,如果有许多种订单,那将会引入大量的额外的类,那么代码不是更加混乱,难以维护吗?
小结
.net,j2ee等属于一种框架软件,它们这些框架软件设计的目的是将一个领域中不变的东西先定义好,比如整体结构和一些主要职责(如数据库操作 事务跟踪 安全等),剩余的就是变化的东西,针对这个领域中具体应用产生的具体不同的变化需求,而这些变化东西就是我们这些程序员所要做的,由此可见,设计模式和.net等在思想和动机上是一脉相承,只不过:
1.设计模式更抽象,.net等框架软件是具体的产品代码,我们可以接触到,而设计模式在对每个应用时才会产生具体代码。
2.设计模式是比.net等框架软件更小的体系结构,框架软件中许多具体程序都是应用设计模式来完成的,
3. .net等框架软件只是适合企业计算应用的框架软件,但是GoF的设计模式几乎可以用于任何应用。
作者:洞庭散人
出处:http://phinecos.cnblogs.com/
posted on 2006-09-29 17:24 Phinecos(洞庭散人) 阅读(3410) 评论(6) 编辑 收藏 举报