ColdFusion支持代理吗?
我有几种数据库访问方法包装在try/catch块中:ColdFusion支持代理吗?,coldfusion,delegates,dry,coldfusion-9,Coldfusion,Delegates,Dry,Coldfusion 9,我有几种数据库访问方法包装在try/catch块中: function GetAll() { try { entityLoad("Book"); } catch (any e) { throw (type="CustomException", message="Error accessing database, could not read"); } } function Save(Book book) { try {
function GetAll() {
try {
entityLoad("Book");
}
catch (any e) {
throw (type="CustomException", message="Error accessing database, could not read");
}
}
function Save(Book book) {
try {
entitySave(book);
}
catch (any e) {
throw (type="CustomException", message="Error accessing database, could not save);
}
}
如您所见,try/catch块重复了好几次,其中唯一不同的是消息。是否可以在ColdFusion中创建一个委托,以便我可以执行类似的操作(使用C#lambda表示匿名委托)
根据您的示例,而不是CF9 CF10中的闭包可能允许您执行以下操作:
function GetAll() {
DatabaseOperation( closure(){ entityLoad("Book") } , "could not read");
}
function Save(Book book) {
DatabaseOperation( closure(){ entitySave(book) } , "could not save");
}
function DatabaseOperation(closure action, string error) {
try {
action();
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
(语法可能会有所不同,不记得是否与此完全相同)
或者,我想你也可以在这里使用
评估
function GetAll() {
DatabaseOperation( 'entityLoad("Book")' , "could not read");
}
function Save(Book book) {
DatabaseOperation( 'entitySave(book)' , "could not save");
}
function DatabaseOperation(string action, string error) {
try {
evaluate(action);
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
就我个人而言,我会删除try/catch并在应用程序中使用onError
。cfc
-似乎对掩盖原始错误没有帮助,而是抛出一个更通用的错误
更新:另外两种可能的选择…
另一个当前有效的选项是使用一个公共包装函数,该函数调用DatabaseOperation函数,传入一个私有函数的名称,该函数执行如下实际逻辑:
function GetAll() {
DatabaseOperation( real_GetAll , Arguments , "could not read");
}
private function real_GetAll() {
entityLoad("Book")
}
function Save(Book book) {
DatabaseOperation( real_Save , Arguments , "could not save");
}
private function real_Save(Book book) {
entitySave(book)
}
function DatabaseOperation(any action, struct args , string error) {
try {
action( argumentcollection=args )
}
catch (any e) {
var message = "Error accessing database, " & error;
throw (type="CustomException", message=message);
}
}
如果您不喜欢两次定义函数,但不介意混淆API,可以将方法设置为private,然后使用onMissingMethod:
private function GetAll()
{
entityLoad("Book")
}
private function Save(Book book)
{
entitySave(book)
}
function onMissingMethod( string MethodName , struct MethodArgs )
{
if ( NOT StructKeyExists(Variables,Arguments.MethodName) )
{
throw("The method #Arguments.MethodName# was not found");
}
try
{
var Meth = Variables[Arguments.MethodName];
Meth( ArgumentCollection=Arguments.MethodArgs );
}
catch(any e)
{
var message = "Error accessing database, ";
switch(MethodName)
{
case "GetAll":
message &= "could not read";
break;
case "Save":
message &= "could not save";
break;
}
throw (type="CustomException,message=message);
}
}
谢谢你,彼得。我举的例子只是一个普通的例子。在实际的应用程序中,我们将框架引发的一系列模糊异常与一些对开发人员更有意义的自定义异常打包在一起?这实际上是关于支持匿名函数的。正如Peter所说,这将在下一个版本中出现。是的,这可能是值得澄清的-我经常看到委托
术语,但仍然不能完全确定它们是什么(wikipedia页面并没有真正让它更清楚),但如果只是传递函数并执行它们,这已经是可能的-这只是匿名函数方面还没有出现。是的,匿名函数将是我的目标。据我所知(这可能是错误的),委托只是函数的包装器,允许您像变量一样传递它们。
private function GetAll()
{
entityLoad("Book")
}
private function Save(Book book)
{
entitySave(book)
}
function onMissingMethod( string MethodName , struct MethodArgs )
{
if ( NOT StructKeyExists(Variables,Arguments.MethodName) )
{
throw("The method #Arguments.MethodName# was not found");
}
try
{
var Meth = Variables[Arguments.MethodName];
Meth( ArgumentCollection=Arguments.MethodArgs );
}
catch(any e)
{
var message = "Error accessing database, ";
switch(MethodName)
{
case "GetAll":
message &= "could not read";
break;
case "Save":
message &= "could not save";
break;
}
throw (type="CustomException,message=message);
}
}