• 日志与工厂模式(二)


    关键字:日志 微软企业库 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

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

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

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

    点击这里下载代码

  • 相关阅读:
    性能测试入门
    PHP基础
    SpringCloud五大核心组件
    selenium(八)持续集成
    四种隔离级别和脏读、幻读、不可重复读
    RocketMQ【目录】
    ModelAgnostic Counterfactual Reasoning for Eliminating Popularity Bias in Recommender System
    How Powerful is Graph Convolution for Recommendation?
    ScoreBased Generative Modeling through Stochastic Differential Equations
    Graph Embedding for Recommendation against Attribute Inference Attacks
  • 原文地址:https://www.cnblogs.com/codehunter008/p/1502248.html
Copyright © 2020-2023  润新知