Đây là bản in lại của blog post I did vào ngày 13 tháng 6 năm 2007. Tôi đã sử dụng phương pháp này trong một thời gian và nó hoạt động rất tốt! YMMV.
Ai không thích các hàm do người dùng định nghĩa (UDF)? Nếu bạn đã thực hiện bất kỳ chương trình nào, rất có thể là bạn đã sử dụng chúng rộng rãi. Vấn đề lớn nhất mà mọi người gặp phải là cách bao gồm và sắp xếp chúng trong ứng dụng của bạn.
Những gì tôi đã phát hiện ra rằng hầu hết mọi người làm là tạo một Utils.cfc hoặc UDFs.cfc và cắt và dán UDFs của họ mà họ muốn sử dụng vào các thành phần như chứng minh dưới đây:
<!--- UDFs.cfc --->
<cfcomponent output="false">
<cffunction name="init" access="public” returntype="Any" output="false">
<cfreturn this>
</cffunction>
<cffunction name="myUDF1" access="public" returntype="Any" output="false">
</cffunction>
<cffunction name="myUDF2" access="public" returntype="Any" output="false">
</cffunction>
</cfcomponent>
Khi bạn có tất cả các UDF mà ứng dụng của bạn sẽ sử dụng được dán vào thành phần của bạn, bạn sẽ cần phải làm cho các UDF có sẵn cho ứng dụng của bạn. Hầu như tất cả mọi người tôi đã nhìn thấy điều này tải bởi các thành phần vào phạm vi ứng dụng. Dòng sau được đặt vào onApplicationStart()
nếu bạn đang sử dụng Application.cfc hoặc bởi chỉ cần thêm nó vào Application.cfm nếu bạn đang sử dụng rằng:
<cfset application.functions = CreateObject("component", "udfs").init()>
Cho dù bạn đang sử dụng, Application.cfc hoặc Application.cfm, kết quả là như nhau; tất cả UDF của bạn có sẵn cho ứng dụng của bạn và bạn có thể sử dụng chúng một cách tự do trong suốt. Sự khác biệt duy nhất là tên biến mà bạn sử dụng. Tôi sử dụng application.functions, một số application.utils sử dụng hoặc application.udfs; không quan trọng, một lần nữa, kết quả là như nhau.
Có một vấn đề mà tôi có với cách tiếp cận này mặc dù, nó là cồng kềnh và thành phần UDFs sẽ nhận được rất lớn. Vấn đề với việc có một tập tin thành phần lớn như vậy là chỉnh sửa nó trở thành một cơn ác mộng vì việc cuộn qua hàng ngàn dòng mã không phải là rất thú vị và tôi cũng nhận thấy rằng CFEclipse bogs xuống trên các tệp lớn. Sự sụp đổ mã chắc chắn không cung cấp một số cứu trợ nhưng phải có một cách tốt hơn.
Điều tôi muốn là chỉ có một tệp cho mỗi UDF mà tôi đang sử dụng và một cách để ứng dụng của tôi tải chúng tự động. Lý do đằng sau việc này là để nếu tôi cần chỉnh sửa myUDF1
, tôi chỉ có thể mở tệp myUDF1.cfm
và chỉnh sửa những gì tôi cần. Tôi cũng muốn có thể lấy UDF từ CFLib.org và chỉ cần thả chúng vào ứng dụng của tôi mà không cần phải chỉnh sửa bất kỳ thứ gì. Nếu tôi cần xóa UDF khỏi ứng dụng của mình, nó sẽ dễ dàng như việc xóa tệp UDF và khởi tạo lại ứng dụng của tôi.
Để thực hiện những gì tôi muốn, tôi sửa đổi UDFs.cfc tôi đến 11 dòng mã:
<!--- UDFs.cfc --->
<cfcomponent output="false">
<cfset variables.udfdir = GetDirectoryFromPath(GetCurrentTemplatePath()) & "udfs">
<cfset variables.q = "">
<cffunction name="init" access="public" returntype="Any" output="false">
<cfreturn this>
</cffunction>
<cfdirectory action="list" directory="#variables.udfdir#" filter="*.cfm" name="variables.q">
<cfoutput query="variables.q">
<cfinclude template="udfs\#name#">
</cfoutput>
</cfcomponent>
Vì vậy, chính xác những gì đang xảy ra?
Tóm lại, đây là những gì đang xảy ra: Tôi có một thư mục có tên là udfs
trong cùng thư mục mà tôi có UDFs.cfc của mình. Đây là thư mục mà tôi đặt tất cả các tệp UDF CFM của tôi. Những gì UDFs.cfc làm là quét thư mục này khi nó được gọi và tự động bao gồm mỗi tệp CFM mà nó tìm thấy. Do đó, nó tự động tải bất kỳ UDF nào trong thư mục UDF vào chính nó (thường được gọi là "mixin").
Vì vậy, mục tiêu của tôi đã đạt được! Tôi có mỗi UDF trong tập tin riêng của nó vì vậy tôi không phải di chuyển qua một tập tin thành phần lớn để tìm nó. Bây giờ tôi có thể mở và chỉnh sửa nó một cách dễ dàng. Chỉ cần nhìn vào thư mục, tôi biết UDF đang sử dụng ứng dụng nào. Tôi có thể tự động thêm UDF từ CFLib.org bằng cách chỉ lưu văn bản từ trình duyệt vào một tệp trong thư mục. Plus nếu tôi không còn cần phải sử dụng UDF trong ứng dụng của tôi, tôi chỉ cần xóa các tập tin từ thư mục và nó bị xóa khỏi ứng dụng của tôi trong lần khởi động lại tiếp theo. Tất cả điều này được thực hiện mà không cần phải chạm vào tập tin UDFs.cfc chính.
Dưới đây là ví dụ về một trong những tệp CFF CFM trông như thế nào. Tệp này được gọi là fullLeft.cfm
và nằm trong thư mục UDFs.
<!--- fullLeft --->
<cffunction name="fullLeft" access="public" displayname="fullLeft" returntype="string" output="false">
<cfargument name="str" type="string" required="true">
<cfargument name="count" type="numeric" required="true">
<cfif not refind("[[:space:]]", arguments.str) or (arguments.count gte len(arguments.str))>
<cfreturn Left(arguments.str, arguments.count)>
<cfelseif reFind("[[:space:]]",mid(arguments.str,arguments.count+1,1))>
<cfreturn left(arguments.str,arguments.count)>
<cfelse>
<cfif count-refind("[[:space:]]", reverse(mid(arguments.str,1,arguments.count)))>
<cfreturn Left(arguments.str, (arguments.count-refind("[[:space:]]", reverse(mid(str,1,arguments.count)))))>
<cfelse>
<cfreturn left(arguments.str,1)>
</cfif>
</cfif>
</cffunction>
Ý tưởng rất hay, tôi sẽ phải thử nghiệm với cách tiếp cận của bạn. – kevink
Tôi đã làm điều này trong một thời gian dài với kết quả tốt, là tốt. –
Tôi đã thực hiện điều này ngày hôm qua và phải nói rằng nó hoạt động rất tốt. Tôi cũng sử dụng cách tiếp cận để đơn giản hóa các bài kiểm tra đơn vị của mình bằng cách lặp qua thư mục để đảm bảo không có chức năng nào có thể bỏ qua. Rất trơn. – kevink