扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:builder.com.cn 2007年3月26日
关键字: COLDFUSION CFC 状态模式
在本页阅读全文(共19页)
本文也可以在技术文章下载处下载,且以一种更易于管理的文本格式提供所有示例代码。
ColdFusion MX中ColdFusion组件(CFCs)的引入,开启了在CF中面向对象编程的新篇章。在应用开发人员和程序员开始思考面向对象编程(OOP)时,总会提到设计模式的概念。
在这样的背景下,本文中我们将讨论一下状态模式:它的目的是什么,可以解决什么问题,以及如何利用CFCs实现。同时,本文这里包含了一些示例代码。你还可以从此文的下载版中得到这些代码。
问题描述
首先,我们来看一个问题,这个问题可能会使我们考虑用状态模式作为解决方案。在我的例子中,我将创建一个简单的内容管理系统,系统中的内容项可能包含这样几个状态:起草、预览、等待发行许可、已发行。内容项还可以包含多个要执行的方法:保存、许可该项、拒绝该项等。我们需要根据内容项不同的状态和将要执行的方法,分别以不同的方式做出反应。
我们可以有几种方法解决这个问题。第一种可能的方法是为每种状态与行为组合创建不同的方法。CFS内容项如列表A所示,列表B显示了使用CFC的测试运行结果。
列表 A
<cfcomponent name="MethodExplosionContentItem" hint="I am a per-reqeust CFC that represents a Content Item, but does not use the State pattern.">
<cffunction name="init" access="public" returntype="MethodExplosionContentItem" hint="Constructor.">
<cfreturn this />
</cffunction>
<cffunction name="saveDraft" access="public" returntype="void" output="true" hint="">
<cfoutput>
Draft: saving content item...<br/>
</cfoutput>
</cffunction>
<cffunction name="savePublished" access="public" returntype="void" output="true" hint="">
<cfoutput>
Published: setting the content to draft mode...<br/>
</cfoutput>
</cffunction>
<cffunction name="approveDraft" access="public" returntype="void" output="true" hint="">
<cfoutput>
Draft: saving content item and alerting reviewer about content for review...<br/>
</cfoutput>
</cffunction>
<cffunction name="approveReview" access="public" returntype="void" output="true" hint="">
<cfoutput>
Review: alerting content author that content is approved...<br/>
Review: marking content as ready for publish approval...<br/>
</cfoutput>
</cffunction>
<cffunction name="approvePublishApproval" access="public" returntype="void" output="true" hint="">
<cfoutput>
Publish approval: Marking content as deployed...<br/>
Publish approval: Pushing live and updating content cache...<br/>
</cfoutput>
</cffunction>
<cffunction name="rejectReview" access="public" returntype="void" output="true" hint="">
<cfoutput>
Review: alerting content author that content is rejected...<br/>
Review: setting back to draft mode...<br/>
</cfoutput>
</cffunction>
<cffunction name="rejectPublishApproval" access="public" returntype="void" output="true" hint="">
<cfoutput>
Publish approval: alerting reviewer that publishing is rejected...<br/>
Publish approval: setting back to review mode...<br/>
</cfoutput>
</cffunction>
</cfcomponent>
列表B
<h2>First, method explosion with separate methods for all actions and statues:</h2>
<cfset contentMethodExplosion = createObject('component','MethodExplosionContentItem').init() />
<cfset contentMethodExplosion.saveDraft() />
<cfset contentMethodExplosion.approveDraft() />
<cfset contentMethodExplosion.approveReview() />
<cfset contentMethodExplosion.approvePublishApproval() />
<cfset contentMethodExplosion.savePublished() />
<cfset contentMethodExplosion.approveDraft() />
<cfset contentMethodExplosion.rejectReview() />
<hr/>
<cfset contentMethodExplosion2 = createObject('component','MethodExplosionContentItem').init() />
<cfset contentMethodExplosion2.rejectReview() />
<cfset contentMethodExplosion2.saveDraft() />
<cfset contentMethodExplosion2.approveDraft() />
<cfset contentMethodExplosion2.approveReview() />
<cfset contentMethodExplosion2.rejectPublishApproval() />
<hr/>
从上面的运行看代码能够满足要求,它的确按照我们的要求运行。然而,对于它是如何工作的,存在几个问题。首先是拥有大量的方法,每个状态和行为组合对应一个方法。我们要有saveDraft(), savePublished(), rejectReview(), rejectPublishApproval()等方法。如果这时你注意到这一点,不错因为我们应该注意。因为如果我们增加几个状态或行为,那么状态和事件组合将会呈指数级增加。三个状态和三个行为需要九个方法,四个状态和四个行为要有十六个方法等等。很明显,这不是一个可以升级的方案。
这还不是全部,还存在另一个问题,我们需要客户端代码(在本例中就是简单的测试模板)跟踪内容项的状态变化。如果失去状态跟踪,本该调用approveDraft()方法却意外调用了approvePublishApproval()方法,就会导致内容项进入错误状态,此时可能就会发生错误。
或者导致发布本不应该发布的内容项。关键问题是客户端代码本不应该跟踪内容项状态,它的状态应该有状态项自身维护。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者