9

因此,当涉及到我们的网站时,我所工作的公司的做法非常杂乱无章。我们所有的脚本都是包含 cfincludes 的程序化脚本。我一直想将它组织成一个内部 API,其他 Web 开发人员将使用它来做任何事情(因为进行更改让我通过并找到需要更新更改的每个其他实例)。

我终于有一个活生生的例子,并展示了老板。它遵循我认为的正常方法(来自我的谷歌搜索)。服务层 > Gateway & DAO > Beans,带有一些工厂来帮助创建对象。它运行良好,完全符合我的要求。他对此印象深刻,并同意我们需要修饰我们的代码并更好地组织它,但没有看到使用这种面向对象的 API 调用大量 cfinclude 列表来完成相同事情的优势。本质上,从他解释 cfincludes 的方式来看,它的工作方式与方法调用相同。

他询问了我的方法与此 cfinclude 相比的优势,而在我的一生中,除了将类似的数据全部分组到一个对象中之外,我真的找不到任何明显的优势。还有什么其他的,或者更确切地说,使用 cfinclude 方法可能是有利的?

4

3 回答 3

25

可读性、维护性和对经过验证的面向对象范式的遵守将是使用真正的 CFC / 对象服务层构建 ColdFusion 应用程序的最重要方面,而不是大量的 cfincludes,这充其量是业余的,并且可能导致垃圾最糟糕的收藏噩梦。

可读性

假设您有一个名为 _queries.cfm 的 cfinclude,其中包含对您的应用程序的所有调用。然后,在您的员工页面顶部,就在您输出所有员工之前,您执行以下操作:

<cfinclude template="_queries.cfm" />

<cfoutput query="employeeQry">

employeeQry 是从哪里来的?它是该模板中的查询之一吗?它有什么作用?当我只需要员工时,是否需要包含该模板?如果它有网站中的所有查询...是否都需要每次都包含在内?

为什么不写一些更具可读性的东西,比如:

<cfset employeeQry = request.model.queries.getEmployees() />

<cfoutput query="employeeQry">

啊,我们走了。一目了然,在不了解您系统的细微差别的情况下,我可以立即识别:

  • employeeQry 变量的来源
  • 我从哪个缓存的 CFC 调用查询
  • 我正在调用一个且只有一个查询,而不是大量包括一系列查询,页面不需要这些查询。

将业务逻辑封装在服务层 (CFC) 中可提高代码的可读性,这将在您进入下一个主题时产生影响。

维护

您获得了一个您负责的新 CF 应用程序,并打开员工页面以找到<cfinclude template="_queries.cfm">上面的模板。

在其中,原始开发人员留下了一条评论,大意是:“我们不要运行所有查询,我们只运行基于参数的特定查询”,然后您会看到如下内容:

<cfswitch case="#param#">
  <cfcase value="employee">
    <cfinclude template="_employeeQry.cfm">
  </cfcase>
  <cfcase value="employees">
    <cfinclude template="_employeesQry.cfm">
  </cfcase>
  <cfcase value="employeesByDept">
    <cfinclude template="_employeesByDept.cfm">
  </cfcase>
</cfswitch>

...所以你看着这个并想,嗯...我需要修改 employeesByDept 查询,所以你打开那个模板并找到:

<!--- employees by department --->
<cfif args.order_by is "ASC">
  <cfinclude template="_employeeQryByDeptOnASCOrder.cfm">
<cfelse>
  <cfinclude template="_employeeQryByDeptOnDESCOrder.cfm">
</cfif>

......到了这一点,你想朝自己的脸开枪。

这是一个夸张的例子,但在 ColdFusion 世界中再熟悉不过了;构建企业级应用程序时的业余爱好者心态。这种“包含在包含中”的噩梦是 CF 开发人员比您想象的更频繁地处理的事情。

解决方法很简单!

一个单一的 CFC,它封装了为您的员工生成查询的业务逻辑。

<cfcomponent>

  <cffunction name="getEmployees" returntype="query">

    <cfquery name="tmp">
    select employeeID, name, age
    from employees
    </cfquery>

    <cfreturn tmp />
  </cffunction>

  <cffunction name="getEmployeesByDept" returntype="query">
    <cfargument name="deptID">
    <cfargument name="order_by" required="false" default="ASC">

    <cfquery name="tmp">
    select employeeID, name, age
    from employees e
    inner join empToDept etd on (e.employeeID = etd.employeeID)
    where etd.deptID = #arguments.deptID#
    order by name #iif(arguments.order_by is 'asc',de('asc'),de('desc'))#
    </cfquery>

    <cfreturn tmp />

  </cffunction>

</cfcomponent>

现在,在查询员工数据库时,您对希望生成的所有信息都有一个单一的参考点,并且可以一次对其进行参数化/调整,而无需在包含中的包含中挖掘大量包含...很麻烦,而且很难保持直截了当(即使有足够的源代码控制)。

它优雅地允许您编写一行:

<cfset empQry = request.model.queries.getEmployees() />

或者

<cfset empQry = request.model.queries.getEmployeesByDept(14,'DESC') />

并使您的代码维护工作变得更加容易

遵守经过验证的面向对象范式

您的老板宣布有一位 Java 摇滚明星加入了团队。你非常渴望和兴奋地和他坐下来,因为过去几年你主要被困在 CF 中,并希望有机会向他展示你的一些东西,并可能向他学习。

“那么,应用程序如何访问数据?” 他问你。

“哦,我们有一系列的查询,我们在各个页面上调用,根据参数,我们会拉取不同类型的信息。”

“很好”,他说,“所以……你有一个数据对象模型的服务层,这很棒。”

不是真的,你认为。它只是包含在包含中......但他继续前进,

“这太好了,因为我们要添加的新东西之一是 Contractor 对象,它基本上是 Employee 的一个子集,他将拥有一些不同的功能,但总体上会非常像 Employee。我们'将继续并继承 Employee 类,并覆盖其中一些查询......"

...现在你迷路了。因为没有子类包含。包含中没有继承。包含不了解域或业务对象,也不了解它应该如何与其他对象交互。

cfinclude 可以方便地重用常见元素,例如页眉或页脚。它们不是反映业务对象复杂性的机制。

当您将 CFC 设计/构造/实现为反映应用程序实体的对象时,您说的是一种通用语言:OO。这意味着它没有为您提供基于经过验证的结构设计系统的能力,而是将“OO-ness”的语言扩展到其他技术的程序员。Java 程序员、C++/C# 程序员等...任何对面向对象开发有一定了解的人都会自动使用您的语言并能够与您和您的系统一起工作。

请注意最后一点:并非每个应用程序都需要面向对象。如果您的老板希望您快速创建一个员工表的 XML 转储文件并将其放到网站上——是的,您可能会为此放弃整个 oo 模型。但是,如果您要从头开始构建应用程序,并且它将包含员工、用户、部门、查询、角色、规则、票证……简而言之:域中的实体,是时候搁置 cfincludes作为您重用代码的主要工具。

哦,还有 PS:我在顶部留下的关于垃圾收集的小便条——不是开玩笑。我看到 CF 应用程序构建不正确,因此 Application.cfc本身调用 cfincludes,并且在将 CF 连接到可以监控 GC 中对象的实时创建/销毁的 JVM之后,我看到内存看起来像 EKG 监视器.

不好。

于 2012-01-20T02:21:46.933 回答
1

肖恩的回答肯定涵盖了要点。把所有这些总结成你的老板会理解的关键点.. CFC 方法将在维护方面为他节省大量资金,并让他的开发人员更快乐,因为他们的工作会更容易,并且熟练/积极进取的开发人员的保留率将比他继续使用意大利面条代码作为标准时高得多。

于 2012-01-20T02:49:45.033 回答
1

我完全同意 Shawn 的回答……如果您想将代码提升到更高的水平,请使用框架!然后它会真正为您和其他开发人员节省大量时间,因为每个人都会遵守自己的标准。

我个人的偏好是 Coldbox,但任何流行的 MVC/OO 框架都可以——Coldbox、Mach-II、Model-Glue、FW/1。我也听说过关于 CFWheels 的好消息,但还没有使用过。

于 2012-01-20T16:59:36.213 回答