zoukankan      html  css  js  c++  java
  • 微软常用的组件设计思想-‘工厂的工厂类’

    我们在写代码的时候,经常碰到各种软件的设计思想,也许,你是一个弱小的码农,也逃不了设计的思想已悄悄的走向你的身边,只是我们不知道这叫啥罢了。

    诸如,我们经常玩的三层BLL DAL UI 那么还有一个东东,就是工厂Factory起到桥接作用。

    回忆起三层,Factory 是一种设计模式

    工厂方法模式的结构图如下:

    Product定义了工厂方法所创建的对象的接口。
    ConcreteProduct实现Product接口, 定义了具体对象。
    Creator定义了具体对象创建的工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象
    ConcreteCreator实现Creator接口,重定义工厂方法以返回一个ConcreteProduct实例。
    示例
    我们以实现一个文档处理系统来看一下工厂方法模式的应用。
    首先定义文档类型的接口和两个具体的文档类型

    复制代码
     1     public interface IFile
    2 {
    3 void New();
    4 void Save();
    5 }
    6 public class DocFile : IFile
    7 {
    8 public void New()
    9 {
    10 Console.WriteLine("New Doc Create");
    11 }
    12 public void Save()
    13 {
    14 Console.WriteLine("Save Doc");
    15 }
    16 }
    17 public class TxtFile : IFile
    18 {
    19 public void New()
    20 {
    21 Console.WriteLine("New Txt Create");
    22 }
    23 public void Save()
    24 {
    25 Console.WriteLine("Save Txt");
    26 }
    27 }
    复制代码

    接着实现对象创建的工厂方法及具体文档的创建工厂

    复制代码
     1     interface IFileFactory
    2 {
    3 IFile Create();
    4 }
    5 public class DocFileFactory : IFileFactory
    6 {
    7 public IFile Create()
    8 {
    9 return new DocFile();
    10 }
    11 }
    12 public class TxtFileFactory : IFileFactory
    13 {
    14 public IFile Create()
    15 {
    16 return new TxtFile();
    17 }
    18 }
    复制代码

    最后看一下如何调用

    复制代码
     1     static void Main(string[] args)
    2 {
    3 IFile docFile = (new DocFileFactory()).Create();
    4 docFile.New();
    5 docFile.Save();
    6 IFile txtFile = (new TxtFileFactory()).Create();
    7 txtFile.New();
    8 txtFile.Save();
    9 Console.ReadLine();
    10 }

    回忆到此,想必,大家对工厂有个很好的体会了,不过,今天,我们看看微软是如何在工厂的基础上动手脚的

    上图是微软最喜欢用的工厂设计模式思想(此例为日志工厂)。

    我们来分析上面的思路

    1)为了能够使程序在加载的时候,动态适应改变不同的工厂,而引入了LoggerFactory工厂类

    2)减轻了每次在代码中去重复的指定工厂实现类

    3)上图中,第一步通过LoggerFactory工厂类SetCurrent()指定当前工厂实现类TraceSourceLogFactory

    4) LoggerFactory工厂类调用方法CreateLog()直接调用TraceSourceLogFactory工厂类Create(),进而创建出TraceSourceLog 现实类

    我们来看看具体的代码:

    1)ILogger接口:

       public interface ILogger
        {
            /// <summary>
            /// Log debug message
            /// </summary>
            /// <param name="message">The debug message</param>
            /// <param name="args">the message argument values</param>
            void Debug(string message, params object[] args);
    
            /// <summary>
            /// Log debug message
            /// </summary>
            /// <param name="message">The message</param>
            /// <param name="exception">Exception to write in debug message</param>
            void Debug(string message,Exception exception,params object[] args);
    
            /// <summary>
            /// Log debug message 
            /// </summary>
            /// <param name="item">The item with information to write in debug</param>
            void Debug(object item);
    
            /// <summary>
            /// Log FATAL error
            /// </summary>
            /// <param name="message">The message of fatal error</param>
            /// <param name="args">The argument values of message</param>
            void Fatal(string message, params object[] args);
    
            /// <summary>
            /// log FATAL error
            /// </summary>
            /// <param name="message">The message of fatal error</param>
            /// <param name="exception">The exception to write in this fatal message</param>
            void Fatal(string message, Exception exception,params object[] args);
    
            /// <summary>
            /// Log message information 
            /// </summary>
            /// <param name="message">The information message to write</param>
            /// <param name="args">The arguments values</param>
            void LogInfo(string message, params object[] args);
    
            /// <summary>
            /// Log warning message
            /// </summary>
            /// <param name="message">The warning message to write</param>
            /// <param name="args">The argument values</param>
            void LogWarning(string message, params object[] args);
    
            /// <summary>
            /// Log error message
            /// </summary>
            /// <param name="message">The error message to write</param>
            /// <param name="args">The arguments values</param>
            void LogError(string message, params object[] args);
    
            /// <summary>
            /// Log error message
            /// </summary>
            /// <param name="message">The error message to write</param>
            /// <param name="exception">The exception associated with this error</param>
            /// <param name="args">The arguments values</param>
            void LogError(string message, Exception exception, params object[] args);
        }

    2)日志接口TraceSourceLog实现类:

     public sealed class TraceSourceLog
            :ILogger
        {
            #region Members
    
            TraceSource source;
    
            #endregion
    
            #region  Constructor
    
            /// <summary>
            /// Create a new instance of this trace manager
            /// </summary>
            public TraceSourceLog()
            {
                // Create default source
                source = new TraceSource("NLayerApp");
            }
    
            #endregion
    
    
            #region Private Methods
    
            /// <summary>
            /// Trace internal message in configured listeners
            /// </summary>
            /// <param name="eventType">Event type to trace</param>
            /// <param name="message">Message of event</param>
            void TraceInternal(TraceEventType eventType, string message)
            {
    
                if (source != null)
                {
                    try
                    {
                        source.TraceEvent(eventType, (int)eventType, message);
                    }
                    catch (SecurityException)
                    {
                        //Cannot access to file listener or cannot have
                        //privileges to write in event log etc...
                    }
                }
            }
            #endregion
    
            #region ILogger Members
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void LogInfo(string message, params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message))
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    TraceInternal(TraceEventType.Information, messageToTrace);
                }
            }
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void LogWarning(string message, params object[] args)
            {
    
                if (!String.IsNullOrWhiteSpace(message))
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    TraceInternal(TraceEventType.Warning, messageToTrace);
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void LogError(string message, params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message))
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    TraceInternal(TraceEventType.Error, messageToTrace);
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="exception"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void LogError(string message, Exception exception, params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message)
                    &&
                    exception != null)
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    var exceptionData = exception.ToString(); // The ToString() create a string representation of the current exception
    
                    TraceInternal(TraceEventType.Error, string.Format(CultureInfo.InvariantCulture, "{0} Exception:{1}", messageToTrace, exceptionData));
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void Debug(string message, params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message))
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    TraceInternal(TraceEventType.Verbose, messageToTrace);
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="exception"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void Debug(string message, Exception exception,params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message)
                    &&
                    exception != null)
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    var exceptionData = exception.ToString(); // The ToString() create a string representation of the current exception
    
                    TraceInternal(TraceEventType.Error, string.Format(CultureInfo.InvariantCulture, "{0} Exception:{1}", messageToTrace, exceptionData));
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="item"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void Debug(object item)
            {
                if (item != null)
                {
                    TraceInternal(TraceEventType.Verbose, item.ToString());
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="args"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void Fatal(string message, params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message))
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    TraceInternal(TraceEventType.Critical, messageToTrace);
                }
            }
    
            /// <summary>
            /// <see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/>
            /// </summary>
            /// <param name="message"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            /// <param name="exception"><see cref="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILogger"/></param>
            public void Fatal(string message, Exception exception,params object[] args)
            {
                if (!String.IsNullOrWhiteSpace(message)
                    &&
                    exception != null)
                {
                    var messageToTrace = string.Format(CultureInfo.InvariantCulture, message, args);
    
                    var exceptionData = exception.ToString(); // The ToString() create a string representation of the current exception
    
                    TraceInternal(TraceEventType.Critical, string.Format(CultureInfo.InvariantCulture, "{0} Exception:{1}", messageToTrace, exceptionData));
                }
            }
    
    
            #endregion
        }

    3) ILoggerFactory接口:

     /// <summary>
        /// Base contract for Log abstract factory
        /// </summary>
        public interface ILoggerFactory
        {
            /// <summary>
            /// Create a new ILog
            /// </summary>
            /// <returns>The ILog created</returns>
            ILogger Create();
        }

    4)TraceSourceLogFactory 接口ILoggerFactory实现类

     /// <summary>
        /// A Trace Source base, log factory
        /// </summary>
        public class TraceSourceLogFactory
            :ILoggerFactory
        {
            /// <summary>
            /// Create the trace source log
            /// </summary>
            /// <returns>New ILog based on Trace Source infrastructure</returns>
            public ILogger Create()
            {
                return new TraceSourceLog();
            }
        }

    5)LoggerFactory 工厂类

     /// <summary>
        /// Log Factory
        /// </summary>
        public static class LoggerFactory
        {
            #region Members
    
            static ILoggerFactory _currentLogFactory = null;
    
            #endregion
    
            #region Public Methods
    
            /// <summary>
            /// Set the  log factory to use
            /// </summary>
            /// <param name="logFactory">Log factory to use</param>
            public static void SetCurrent(ILoggerFactory logFactory)
            {
                _currentLogFactory = logFactory;
            }
    
            /// <summary>
            /// Createt a new <paramref name="Microsoft.Samples.NLayerApp.Infrastructure.Crosscutting.Logging.ILog"/>
            /// </summary>
            /// <returns>Created ILog</returns>
            public static ILogger CreateLog()
            {
                return (_currentLogFactory != null) ? _currentLogFactory.Create() : null;
            }
    
            #endregion
        }

    在全局的项目配置里加入设置当前工厂方法

    细心的朋友可以看出,下面还有其它类似的工厂,哈哈,换汤不换药。

    调用:  LoggerFactory.CreateLog().LogError(Messages.error_CannotPerformTransferInvalidAccounts);

    小结:设计的思想,就是从人的思想角度出发,驱动代码的构造。好的设计思想,往往都是从代码中提炼而来,从而推动了更优秀的设计思想,不断的创新迭出!

    做为程序员多看看优质的源码,可以快速的吸收别人的精髓,这也是一种‘智取’。

    作者:谷歌's谷歌's博客园
    出处:http://www.cnblogs.com/laogu2/ 欢迎转载,但任何转载必须保留完整文章,在显要地方显示署名以及原文链接。如您有任何疑问或者授权方面的协商,请给我留言
  • 相关阅读:
    Thread记录
    反射的学习笔记--sql语句生成
    Index was outside the bounds of the array. (Microsoft.SqlServer.Smo)
    contains 方法
    mysql connector 和 sqlserver ado.net 的区别
    javascript slice
    javascript bind
    转,SelectNodes + XPath
    jsgen 搭建
    【转】基于第一个PhoneGap(cordova)的应用详解
  • 原文地址:https://www.cnblogs.com/laogu2/p/5912153.html
Copyright © 2011-2022 走看看