在一个项目中我使用到了软件工厂的工具帮助生成了对数据库的CRUD的方法,在Logic中需要对数据层进行封装,以提供对实体操作的接口,封装后的代码如:
代码语言:javascript复制public bool AddNews(News news)
{
try
{
newsRep.Add(news);//执行数据库操作
return true;
}
catch (Exception ex)
{
LogLogic.AddSystemLog(this, ex);//记录异常日志
return false;//返回false
}
}
public bool UpdateNews(News news)
{
try
{
newsRep.Save(news);
return true;
}
catch (Exception ex)
{
LogLogic.AddSystemLog(this, ex);
return false;
}
}
public bool DeleteNews(int newsID)
{
try
{
newsRep.Remove(newsID);
return true;
}
catch (Exception ex)
{
LogLogic.AddSystemLog(this, ex);
return false;
}
}
一看上面的代码,其实都是实现调用一个数据访问层的方法,如果调用完成则返回成功,调用异常则返回失败。同样的逻辑,有必要重复的写这样的代码吗?虽然Ctrl C和Ctrl V的方式可以避免重复的手工输入重复的代码,但是从代码的艺术性来说,这样的代码明细不够优雅。此时我想到的第一个办法就是使用委托。但是数据访问层的方法传入的参数数目和类型又不相同,不能使用一个委托来实现。从一般的逻辑来说这里使用委托是必然的,但是一般的委托又不能适用于各自数据访问层的方法,这是就要使用.net2.0中的匿名函数来实现了。
首页我们定义一个所有Logic类的基类BaseLogic,在其中申明一个匿名函数的委托void TryMethod(),然后将公共的try catch部分提取出来形成方法TryIt。
代码语言:javascript复制public class BaseLogic
{
protected delegate void TryMethod();
protected bool TryIt(TryMethod tryMethod)
{
try
{
tryMethod();//调用委托中的匿名函数
return true;
}
catch (Exception ex)
{
LogLogic.AddSystemLog(this, ex);
return false;
}
}
}
接下来就是改写前面的不够优雅的函数,改成使用匿名函数的方式:
代码语言:javascript复制public class NewsLogic:BaseLogic, INewsLogic
{
//…省略其他代码…
public bool AddNews(News news)
{
return TryIt(delegate()//使用匿名函数,调用基类中的TryIt方法
{
newsRep.Add(news);
}
);
}
public bool UpdateNews(News news)
{
return TryIt(delegate()
{
newsRep.Save(news);
}
);
}
public bool DeleteNews(int newsID)
{
return TryIt(delegate()
{
newsRep.Remove(newsID);
}
);
}
}
对比一下现在的代码和前面的代码,明显感觉代码清爽了很多,匿名函数的使用使得代码更易修改和维护。