zoukankan      html  css  js  c++  java
  • 日志与工厂模式(二)

    关键字:日志 微软企业库 Log4net 工厂模式

    上一篇我们介绍了一个简单的日志组件,SimpleLog,实现了一个ISimpleLog接口与三个具体的日志类。现在我们需要系统中的日志是可以被替换的,即可以使用我们自己开发的SimpleLog日志组件,也可以使用微软企业库的日志组件或者是Log4net组件等等。闲话少说,我们直接进入代码。

    首先,我们定义一个日志接口。

    public interface ILog {
        void AddLog(string Msg);
        void AddLog(string Msg, DateTime time);
    }

    因为我们要使用不同类型的日志组件,所以我们需要对这些日志组件进行简单的包装,以便不同的日志组件能符合我们定义的接口。

    先来包装SimpleLogWrapper:

    public class SimpleLogWrapper {
        public readonly string SimpleLogClassName = ConfigurationManager.AppSettings["SimpleLogClassName"];

        public void AddLog(string text) {
            ISimpleLog log = (ISimpleLog)Assembly.Load("IVSoft.Log.SimpleLog").CreateInstance(SimpleLogClassName);
            log.AddLog(text);
        }

        public void AddLog(string Msg, DateTime time) {
            ISimpleLog log = (ISimpleLog)Assembly.Load("IVSoft.Log.SimpleLog").CreateInstance(SimpleLogClassName);
            log.AddLog(Msg, time);
        }
    }

    再包装微软企业库的日志组件(微软企业库日志的使用方法可以看http://www.cnblogs.com/Terrylee/archive/2005/11/02/266999.html):

    public class MSLogWrapper : ILog {
        public void AddLog(string Msg) {
            AddLog(Msg, DateTime.Now);
        }
        public void AddLog(string Msg, DateTime time) {
            LogEntry log = new LogEntry();
            log.Message = Msg;
            log.TimeStamp = time;
            log.Title = "";
            Logger.Write(log);
        }
    }

    再来包装Log4net的日志组件(Log4net日志组件的使用方法可以看http://blog.csdn.net/zhoufoxcn/archive/2008/03/26/2220533.aspx):

    public class Log4netWrapper :ILog {
        public void AddLog(string Msg) {
            AddLog(Msg, DateTime.Now);
        }

        public void AddLog(string Msg, DateTime time) {
            //创建日志记录组件实例
            log4net.ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
            //记录错误日志
            log.Info(Msg);
        }
    }

    包装完成之后,我们就可以再客户端的代码进行调用了,但是我们现在想通过配置文件(App.config)来设置使用的日志,这样方便日志的更新,而且客户端的代码也是不用更改的,那么我们这个时候就请出“工厂模式”,看如下代码:

    public class LogFactory {
        public readonly string LogAssemblyName = ConfigurationManager.AppSettings["LogAssemblyName"];
        public readonly string LogNameSpaceClassName = ConfigurationManager.AppSettings["LogNameSpaceClassName"];

        public ILog GetLogInstance() {
            return (ILog)Assembly.Load(LogAssemblyName).CreateInstance(LogNameSpaceClassName);
        }
    }

    这里面用到了反射,通过反射来调用相应的DLL并创建配置中指定的日志类的实例。

    这样我们的客户端的代码就可以这么写了:

    LogFactory factory = new LogFactory();
    ILog log = factory.GetLogInstance();
    log.AddLog("测试日志消息");

    我们在来看看App.config的配置文件中与日志工厂相关的配置节:

    <appSettings>
        <add key="LogAssemblyName" value="IVSoft.Log.MSLogWrapper" />
        <add key="LogNameSpaceClassName" value="IVSoft.Log.MSLogWrapper" />
    </appSettings>

    其中:LogAssemblyName 是指日志组件所在的DLL文件名,我们这里都是 XXXLogWrapper;LogNameSpaceClassName是指日志组件的类名,包括名称空间。

    这样,将来可以通过更改配置文件的相关节来使用不同的日志组件,而你的这段客户端代码是不需要做任何的更改的,这就将客户端代码与日志组件的代码做了解耦,而做到这一点的正式“工厂模式”。

    下面我们来看看工厂模式的定义:

    Factory Method模式是一种对象创建型模式,它把类的实例的创建延迟到子类中完成,父工厂类只定义创建对象的公共接口,而子工厂类则负责生成具体的类的实例。

    虽然我们这里只有一个工厂类,没有子工厂类,但是其实我们是通过了反射完成了这个过程,正常的工厂类我们可能会写死每个日志类(ILog = new MSLogWarpper()),这样就失去了一些灵活性,我们的实现方法是一个变通的做法。

    标准的Factory Method 模式图:

    2009-06-12_164022

    使用工厂模式的最大优点就是将客户代码与实际的类解耦,即使将来更改实际类,客户的代码也不会发生改变。

    何时该使用工厂模式:如果你现在不确定将来要使用那些实际类或者实际类可能会有多个,可以使用工厂模式来返回是实际类的接口(抽象类)。

    这也是我的第一篇有关于设计模式的文章,欢迎大家拍砖。

    点击这里下载代码

  • 相关阅读:
    raise PDFEncryptionError('Unknown algorithm: param=%r' % param) pdfminer.pdfdocument.PDFEncryptionError: Unknown algorithm
    Hive与Hbase的区别
    HIVE—索引、分区和分桶的区别
    MapReduce编程之Semi Join多种应用场景与使用
    MapReduce编程之Map Join多种应用场景与使用
    MapReduce编程之Reduce Join多种应用场景与使用
    Mapreduce——视频播放数据分类统计
    Docker-compose实战——Django+PostgreSQL
    Docker基础教程
    1.node接口搭建--express搭建服务器
  • 原文地址:https://www.cnblogs.com/codehunter008/p/1502248.html
Copyright © 2011-2022 走看看