gpt4 book ai didi

coldfusion - 使用请求范围存储对象

转载 作者:行者123 更新时间:2023-12-04 06:35:56 25 4
gpt4 key购买 nike

我正在使用 CFWheels在 ColdFusion 中开发应用程序。

我有一个名为 Vote.cfc 的模型.在创建、更新或删除 Vote 对象之前,我需要从另一个模型中获取 post 对象:Post.cfc .投票属于帖子。一个帖子有很多票。

使用来自 post 的数据对象,我需要 to validate the vote跨多个标准和多个功能的对象。我能想到持久化 post 对象以便这些函数可以使用的唯一方法是将其存储在请求范围内。

其他人说这是不好的做法。但我无法找出原因。我认为请求范围是线程安全的,在这种情况下使用它是有意义的。

我的另一种选择是在每个需要它的函数中加载 post 对象的新实例。尽管 Wheels 使用缓存,但这样做会导致请求时间增加 250%。

更新

这是一些示例。首先, Controller 处理查看投票对象是否已经存在。如果是,它会删除它,如果不是,它会创建它。 Controller 功能本质上是一个切换功能。

Votes.cfc Controller

   private void function toggleVote(required numeric postId, required numeric userId)
{
// First, we look for any existing vote
like = model("voteLike").findOneByPostIdAndUserId(values="#arguments.postId#,#arguments.userId#");

// If no vote exists we create one
if (! IsObject(like))
{
like = model("voteLike").new(userId=arguments.userId, postId=arguments.postId);
}
else
{
like.delete()
}
}

型号 VoteLike.cfc

之后,模型中注册的回调会在验证之前触发。它调用一个函数来检索投票所属的 post 对象。函数 getPost() 将帖子存储在请求范围内。它现在可用于模型中的一堆验证函数。
// Load post before Validation via callback in the Constructor
beforeValidation("getPost");

private function getPost()
{
// this.postId will reference the post that the vote belongs to
request.post = model("post").findByKey(this.postId);
}

// Validation function example
private void function validatesIsNotOwnVote()
{
if (this.userId == request.post.userId)
{
// addError(message="You can't like your own post.");
}
}

getPost() 函数的替代方法是使用范围调用“ this.post().userId”来获取 post 对象,如下所示:
private void function validatesIsNotOwnVote()
{
if (this.userId == this.post().userId)
{
addError(message="can't vote on your own post")
}
}

但是我将不得不重复这个范围调用 this.post().userId对于每个功能,我认为这是减慢请求的原因!

最佳答案

根据 OP 中的评论线程更新新答案
由于您正在从 VoteLike.cfc 扩展基本 Vote 对象,因此 CFC 共享一个本地线程安全变量范围(只要您不将其存储在应用程序或服务器范围内,以供其他人使用)。这意味着您只需设置一个值,例如 Variables.Post,一次,然后在 CFC 堆栈中的任何函数中引用该值。
因此,将您的 getPost() 函数更改为:

beforeValidation("getPost");

private function getPost(){
Variables.Post = model("post").findByKey(this.postID);
}
现在,在 VoteLike.cfc 中的任何函数中,您都可以引用 Variables.Post。这意味着您在本地 CFC 变量范围内有一个 Post 实例,您不必通过参数或其他范围传递它。
原答案如下
处理此问题的“最正确”方法是将对象作为参数传递给每个单独的函数。或者将 Post 添加为 Vote 对象的属性,以便 Vote 对象可以访问完整的 Post 对象。
<cffunction name="doTheValidation">
<cfargument name="ThePost" type="Post" required="true" />
<cfargument name="TheVote" type="Vote" required="true" />
<!--- do stuff here --->
</cffunction>
这是一个不好的做法的原因是因为您要求您的对象可以访问可能存在或可能不存在的外部范围,以便完成它们的工作。如果您决定要在单个页面上处理多个投票或帖子,那么您必须摆弄外部范围以使事情正常工作。
你最好传递你的对象,或者使用组合将你的对象以这样一种方式拼凑在一起,以使它们相互了解。
更新
关于性能问题,如果你使用组合将你的对象绑定(bind)在一起,你最终会在内存中只有两个对象,所以你不必实例化一堆不必要的 Post 对象。此外,将 CFC 作为参数传递给函数将通过引用传递 CFC,这意味着它不会在内存中创建 CFC 的副本,这也应该考虑到您的性能问题。
代码示例更新
为了说明上面的“引用”注释,设置以下文件并将它们单独放在一个目录中。
测试对象.cfc :
<cfcomponent output="false">
<cfproperty name="FirstName" displayname="First Name" type="string" />
<cfproperty name="LastName" displayname="Last Name" type="string" />

</cfcomponent>
索引.cfm :
<!--- Get an instance of the Object --->
<cfset MyObject = CreateObject("component", "TestObject") />

<!--- Set the initial object properties --->
<cfset MyObject.FirstName = "Dan" />
<cfset MyObject.LastName = "Short" />

<!--- Dump out the object properties before we run the function --->
<cfdump var="#MyObject#" label="Object before passing to function" />

<!--- Run a function, sending the object in as an argument, and change the object properties --->
<cfset ChangeName(MyObject) />

<!--- Dump out the object properites again, after we ran the function --->
<cfdump var="#MyObject#" label="Object after passing to function" />

<!--- Take a TestObject, and set the first name to Daniel --->
<cffunction name="ChangeName">
<cfargument name="TheObject" type="TestObject" required="true" hint="" />
<cfset Arguments.TheObject.FirstName = "Daniel" />
</cffunction>
当您运行 index.cfm 时,您会注意到,第一个转储的 FirstName 为 Dan,而第二个转储的 FirstName 为 Daniel。这是因为 CFC 通过引用传递给函数,这意味着在该函数中所做的任何更改都会对内存中的原始对象进行。因此没有对象的再创造,所以没有性能影响。

关于coldfusion - 使用请求范围存储对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4878476/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com