科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件利用ColdFusion组件实现状态模式

利用ColdFusion组件实现状态模式

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文向大家展示了如何利用状态模式解决CFC中的方法或条件爆炸问题。虽然模式的应用可能会给系统带来另外的复杂性,但是对它所带来的优点来说这还是值得的。

作者:builder.com.cn 2007年3月26日

关键字:

  • 评论
  • 分享微博
  • 分享邮件

第二种方案

由此看来,我们应该承认“方法爆炸”方案可能不是最好的,或许我们可以简化问题。

理想的情况下,我认为每个内容项只对一个更普通的行为请求做出反应。这将会使内容项需要的方法降低到三个:save(), approve(), and reject()。列表C所示是该方法的测试用例。

列表C

<h2>Next, using conditional logic in Content Item:</h2>
<cfset contentConditional = createObject('component','ConditionalContentItem').init('draft') />
Content item created in <strong>draft</strong>...<br/>
<cfset contentConditional.save() />
<cfset contentConditional.approve() />
<cfset contentConditional.approve() />
<cfset contentConditional.approve() />
<cfset contentConditional.save() />
<cfset contentConditional.approve() />
<cfset contentConditional.reject() />
<hr/>

<cfset contentConditional2 = createObject('component','ConditionalContentItem').init('review') />
Content item created in <strong>review</strong>...<br/>
<cfset contentConditional2.reject() />
<cfset contentConditional2.save() />
<cfset contentConditional2.approve() />
<cfset contentConditional2.approve() />
<cfset contentConditional2.reject() />
<hr/>

很好,这的确看起来很简单,而且注意现在客户端代码不知道下一步状态项应该是什么状态。它只是调用了approve()方法,有内容项本身跟踪调用该方法后该如何做出反应,问题解决了。

但是还不能高兴得太早,我们的确简化了每个内容项的公共接口,并将跟踪状态的职责转移给了内容项本身。但是,我们又该为此付出什么代价呢?

列表D显示了这个版本的CFC代码,我要警告你,这个代码十分糟糕。看看这么多的逻辑条件。每调用一个方法,我需要对所有状态进行条件检查以确定该如何做出反应。并且,增加更多的方法或行为时仍旧意味着爆炸,只不过是一种不同类型的爆炸,在这种情况下,结果是条件语句的爆炸。

列表 D

<cfcomponent name="ConditionalContentItem" 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="ConditionalContentItem" hint="Constructor.">
<cfargument name="initialStatus" type="string" required="true" />
<cfset setStatus(arguments.initialStatus) />
<cfreturn this />
</cffunction>
<cffunction name="save" access="public" returntype="void" output="true" hint="">
<cfset var local = structNew() />
<cfif getStatus() eq 'draft'>
<cfoutput>
Status '#getStatus()#' saving content item...<br/>
</cfoutput>
<cfelseif getStatus() eq 'published'>
<cfoutput>
Status '#getStatus()#' setting the content to draft mode...<br/>
</cfoutput>
<cfset setStatus('draft') />
</cfif>
</cffunction>
<cffunction name="approve" access="public" returntype="void" output="true" hint="">
<cfset var local = structNew() />
<cfif getStatus() eq 'draft'>
<cfoutput>
Status '#getStatus()#' saving content item and alerting reviewer about content for review...<br/>
</cfoutput>
<cfset setStatus('review') />
<cfelseif getStatus() eq 'review'>
<cfoutput>
Status '#getStatus()#' alerting content author that content is approved...<br/>
Status '#getStatus()#' marking content as ready for publish approval...<br/>
</cfoutput>
<cfset setStatus('publishApproval') />
<cfelseif getStatus() eq 'publishApproval'>
<cfoutput>
Status '#getStatus()#' Marking content as deployed...<br/>
Status '#getStatus()#' Pushing live and updating content cache...<br/>
</cfoutput>
<cfset setStatus('published') />
</cfif>
</cffunction>
<cffunction name="reject" access="public" returntype="void" output="true" hint="">
<cfset var local = structNew() />
<cfif getStatus() eq 'review'>
<cfoutput>
Status '#getStatus()#' alerting content author that content is rejected...<br/>
Status '#getStatus()#' setting back to draft mode...<br/>
</cfoutput>
<cfset setStatus('draft') />
<cfelseif getStatus() eq 'publishApproval'>
<cfoutput>
Status '#getStatus()#' alerting reviewer that publishing is rejected...<br/>
Status '#getStatus()#' setting back to review mode...<br/>
</cfoutput>
</cfif>
</cffunction>
<cffunction name="getStatus" access="private" returntype="string" output="false" roles="" hint="I return the status.">
<cfreturn variables.instance.status />
</cffunction>
<cffunction name="setStatus" access="private" returntype="void" output="false" roles="" hint="I set the status.">
<cfargument name="status" type="string" required="true" hint="status" />
<cfset variables.instance.status = arguments.status />
</cffunction>
</cfcomponent>

这种方法可能比第一种方法好,但是我还是认为有太多的缺点。这就是为什么我们转向状态模式,看看是否能够有所帮助。

    • 评论
    • 分享微博
    • 分享邮件
    闂傚倸鍊风欢锟犲矗鎼淬劌绐楅柡鍥╁亹閺嬪酣鏌曡箛瀣仾濠殿垰銈搁弻鏇$疀鐎n亖鍋撻弽顓ㄧ稏闁跨噦鎷�

    婵犵數濮烽。浠嬪焵椤掆偓閸熷潡鍩€椤掆偓缂嶅﹪骞冨Ο璇茬窞闁归偊鍓涢悾娲⒑闂堟单鍫ュ疾濠婂嫭鍙忔繝濠傜墛閸嬨劍銇勯弽銊с€掗柟钘夊暣閺岀喖鎮滈埡鍌涚彋閻庤娲樺畝绋跨暦閸洖鐓涢柛灞剧矋濞堟悂姊绘担绛嬪殐闁搞劋鍗冲畷銏ゅ冀椤愩儱小闂佹寧绋戠€氼參宕伴崱妯镐簻闁靛牆鎳庢慨顒€鈹戦埥鍡椾簼婵犮垺锚铻炴俊銈呮噺閸嬪倹绻涢崱妯诲碍閻庢艾顦甸弻宥堫檨闁告挾鍠庨锝夘敆娓氬﹦鐭楁繛鎾村焹閸嬫捇鏌e☉娆愬磳闁哄本绋戦埞鎴﹀川椤曞懏鈻婄紓鍌欑劍椤ㄥ懘鎯岄崒鐐靛祦閹兼番鍔岄悞鍨亜閹烘垵顏╅悗姘槹閵囧嫰寮介妸褎鍣ョ紓浣筋嚙濡繈寮婚悢纰辨晣鐟滃秹鎮橀懠顒傜<閺夊牄鍔庣粻鐐烘煛鐏炶姤鍠橀柡浣瑰姍瀹曠喖顢橀悩铏钒闂備浇宕垫慨鎶芥⒔瀹ュ鍨傞柦妯猴級閿濆绀嬫い鏍ㄧ☉濞堟粓姊虹涵鍛【妞ゎ偅娲熼崺鈧い鎺嗗亾闁挎洩濡囧Σ鎰板籍閸繄顓洪梺缁樺姇瀵剙螖閸涱喚鍘搁梺鍓插亽閸嬪嫰鎮橀敃鍌涚厱閻庯綆鍋嗘晶顒傜磼閸屾稑绗ч柟鐟板閹煎湱鎲撮崟闈涙櫏闂傚倷绀侀幖顐も偓姘卞厴瀹曞綊鏌嗗鍛紱閻庡箍鍎遍ˇ浼村磿瀹ュ鐓曢柡鍥ュ妼婢ь垰霉閻樿秮顏堟箒闂佹寧绻傚Λ妤呭煝閺囥垺鐓冪憸婊堝礈濮樿泛钃熼柕濞у嫷鍋ㄩ梺缁樺姇椤曨參鍩㈤弴銏″€甸柨婵嗗€瑰▍鍥ㄣ亜韫囨稐鎲鹃柡灞炬礋瀹曢亶顢橀悢濂変紦

    重磅专题
    往期文章
    最新文章