有时,我们在开发的时候,会遇到一些关于日志记录的功能。并且,它们可能是独立于系统业务逻辑的,那么我们就可以将日志做成组件的形式,以方便复用。
以下采用工厂方法模式,来实现日志组件的设计,并保证对功能的扩展不会改变已有的实现。
我们实现三种日志记录类型:错误日志记录、按钮点击日志记录、操作日志记录。
首先,我们创建一个“抽象工厂”【其实是各实例工厂都必须实现的Log接口】,既然是日志记录,那么就需要有日志的实体了。也就是LogEntity,它是一个“抽象实体”,因为不同类型的日志,需要不同的日志实体,所以这里采用LogEntity作为抽象实体,来派生出各具体类型的日志实体。
实现如下:
public interface ILogFactory { void Log(LogEntity logEntity); }
/// <summary> /// 日志实体(抽象基类) /// </summary> public abstract class LogEntity { public override string ToString() { return "LogEntity(abstract class)"; } }
以下是各个实例工厂、和日志实体,实现各自的日志记录逻辑:
/// <summary> /// 记录错误日志实体类 /// </summary> public class ErrorEntity:LogEntity { /// <summary> /// 编号 /// </summary> public string ID { get; set; } /// <summary> /// 用户编号 /// </summary> public string UserID { get; set; } /// <summary> /// 页面URL /// </summary> public string PageUrl { get; set; } /// <summary> /// 错误信息 /// </summary> public string Msg { get; set; } /// <summary> /// 发生时间 /// </summary> public DateTime OperateTime { get; set; } }
public class ErrorFactory : ILogFactory { private const string FullClassName = "LogComponent.ErrorFactory"; public void Log(LogEntity logEntity) { #region check args if (logEntity == null) { throw new ArgumentNullException(string.Format("The Method in {0} occur ArgumentNullException", FullClassName)); } ErrorEntity innerEntity = logEntity as ErrorEntity; if (innerEntity == null) { throw new NullReferenceException(string.Format("The Method in {0} occur NullReferenceException.Because of converting type.", FullClassName)); } if (string.IsNullOrEmpty(innerEntity.Msg)) { throw new Exception(string.Format("The Method in {0} occur logic Exception. Because of the error message is not nullable", FullClassName)); } #endregion //记录日志 string sql = @"INSERT INTO SYSTEMERRORINFO(SE_USERID,SE_PAGEURL,SE_MESSAGE,SE_OPERATETIME) values (:SE_USERID,:SE_PAGEURL,:SE_MESSAGE,:SE_OPERATETIME)"; OracleParameter[] parameters = new OracleParameter[] { new OracleParameter(":SE_USERID",innerEntity.UserID==null?"":innerEntity.UserID), new OracleParameter(":SE_PAGEURL",innerEntity.PageUrl==null?"":innerEntity.PageUrl), new OracleParameter(":SE_MESSAGE",innerEntity.Msg==null?"":innerEntity.Msg), new OracleParameter(":SE_OPERATETIME",innerEntity.OperateTime==DateTime.MinValue?DateTime.Now:innerEntity.OperateTime) }; OracleHelper.ExecuteNonQuery(OracleHelper.ConnectionStringLocalTransaction, CommandType.Text, sql, parameters); } }
/// <summary> /// 点击按钮统计--其中ButtonName为必填字段 /// </summary> public class ClickCountEntity:LogEntity { /// <summary> /// 记录编号 /// </summary> public string ID { get; set; } /// <summary> /// 用户ID /// </summary> public string UserID { get; set; } /// <summary> /// 页面Url /// </summary> public string PageUrl { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime OperateTime { get; set; } /// <summary> /// 路径名称 /// </summary> public string PathName { get; set; } /// <summary> /// 按钮名称 /// </summary> public string ButtonName { get; set; } }
public class ClickCountFactory:ILogFactory { private const string FullClassName = "LogComponent.ClickCountFactory"; private ErrorEntity errorEntity = null; public void Log(LogEntity logEntity) { //check args if (logEntity==null) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur ArgumentNullException.Because of the arg: logEntity is not nullable.", FullClassName); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new ArgumentNullException(string.Format("The method in {0} occur ArgumentNullException.Because of the arg: logEntity is not nullable.", FullClassName)); } ClickCountEntity innerEntity = logEntity as ClickCountEntity; if (innerEntity==null) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur NullReferenceException.Becaues of converting type", FullClassName); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new NullReferenceException(string.Format("The method in {0} occur NullReferenceException..Becaues of converting type", FullClassName)); } if (String.IsNullOrEmpty(innerEntity.ButtonName)) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur Exception.Because of the field ButtonName is not nullable.", FullClassName); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new Exception(string.Format("The method in {0} occur Exception.Because of the field ButtonName is not nullable.", FullClassName)); } string sql = @"INSERT INTO buttonclickstatistic (bs_userid, bs_pageurl, bs_buttonid, bs_operatetime, bs_pathname, bs_buttonname) VALUES (:v_bs_userid, :v_bs_pageurl, :v_bs_buttonid, :v_bs_operatetime, :v_bs_pathname, :v_bs_buttonname)"; OracleParameter[] parameters = new OracleParameter[]{ new OracleParameter(":v_bs_userid",innerEntity.UserID==null?"":innerEntity.UserID), new OracleParameter(":v_bs_pageurl",innerEntity.PageUrl==null?"":innerEntity.PageUrl), new OracleParameter(":v_bs_buttonid",innerEntity.ID==null?"":innerEntity.ID), new OracleParameter(":v_bs_operatetime",innerEntity.OperateTime), new OracleParameter(":v_bs_pathname",innerEntity.PathName==null?"":innerEntity.PathName), new OracleParameter(":v_bs_buttonname",innerEntity.ButtonName) }; try { OracleHelper.ExecuteNonQuery(OracleHelper.ConnectionStringLocalTransaction, CommandType.Text, sql, parameters); } catch (Exception ex) { errorEntity = new ErrorEntity(); errorEntity.Msg = ex.Message + ex.StackTrace; ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw; } } }
/// <summary> /// 操作日志实体类--其中Msg为必填字段 /// </summary> public class OperatingEntity:LogEntity { /// <summary> /// 记录编号 /// </summary> public string ID { get; set; } /// <summary> /// 用户Id /// </summary> public string UserID { get; set; } /// <summary> /// 操作日志 /// </summary> public string Msg { get; set; } /// <summary> /// 操作时间 /// </summary> public DateTime OperatingTime { get; set; } /// <summary> /// 登陆时间 /// </summary> public DateTime LoginTime { get; set; } /// <summary> /// 下线时间 /// </summary> public DateTime LogoutTime { get; set; } }
public class OperatingFactory:ILogFactory { private const string FullClassName = "LogComponent.OperatingFactory"; private ErrorEntity errorEntity = null; public void Log(LogEntity logEntity) { //check args if (logEntity==null) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur ArgumentNullException.Because of the arg: {1} is not nullable", FullClassName, "logEntity"); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new ArgumentNullException(string.Format("The method in {0} occur ArgumentNullException.Because of the arg: {1} is not nullable", FullClassName, "logEntity")); } OperatingEntity innerEntity = logEntity as OperatingEntity; if (innerEntity==null) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur NullReferenceException.Because of Converting type.", FullClassName); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new NullReferenceException(string.Format("The method in {0} occur NullReferenceException.Because of Converting type.", FullClassName)); } if (string.IsNullOrEmpty(innerEntity.Msg)) { errorEntity = new ErrorEntity(); errorEntity.Msg = string.Format("The method in {0} occur Exception.Because of the field:Msg is not nullable.",FullClassName); ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw new Exception(string.Format("The method in {0} occur Exception.Because of the field:Msg is not nullable.", FullClassName)); } //记录日志 string sql = @"INSERT INTO operatinglog(ol_uf_id,ol_msg,ol_op_time,ol_li_time,ol_lo_time) VALUES(:ol_uf_id,:ol_msg,:ol_op_time,:ol_li_time,:ol_lo_time)"; OracleParameter[] paras = new OracleParameter[] { new OracleParameter(":ol_uf_id",innerEntity.UserID==null?"":innerEntity.UserID), new OracleParameter(":ol_msg",innerEntity.Msg), new OracleParameter(":ol_op_time",innerEntity.OperatingTime), new OracleParameter(":ol_li_time",innerEntity.LoginTime), new OracleParameter(":ol_lo_time",innerEntity.LogoutTime), }; try { OracleHelper.ExecuteNonQuery(OracleHelper.ConnectionStringLocalTransaction, CommandType.Text, sql, paras); } catch (Exception ex) { errorEntity = new ErrorEntity(); errorEntity.Msg = ex.Message + ex.StackTrace; ILogFactory logFactory = new ErrorFactory(); logFactory.Log(errorEntity); throw; } } }
在客户端调用的时候,你需要先new 一个你需要的具体的日志实体,然后设置它的属性,比如:
OperatingEntity entity=new OperatingEntity();
//set Property
entity.OperatingTime=DateTime.Now;
.....
然后提供你的实例工厂:
ILogFactory factory=new OperatingFactory();
factory.Log(entity);
扩展的时候,你需要构建你新的日志实体类和新的实例工厂,来实现你的记录逻辑。
原有的实现都无需改动。
原文发布时间为:2011-07-24
本文作者:vinoYang
本文来自云栖社区合作伙伴CSDN博客,了解相关信息可以关注CSDN博客。