你的位置:首页 > ASP.net教程

[ASP.net教程]微软常用的组件设计思想


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

诸如,我们经常玩的三层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/ 欢迎转载,但任何转载必须保留完整文章,在显要地方显示署名以及原文链接。如您有任何疑问或者授权方面的协商,请给我留言。