委托通常可以应用到哪些场合
2014-08-27 11:15
211 查看
分析问题
委托的功能和其名字非常类似,在设计中其思想在于把工作委派给其他特定的类型或者组件。委托的使用者可以理解为工作的分派者,在通常情况下使用者清楚地知道哪些工作需要执行、执行的结果又是什么,但是他却不会亲自地去做这些工作,而是恰当地把这些工作分派出去。
在本节中,笔者将举一个日志读写的例子,来说明委托的实际应用。日志子系统在几乎所有的系统中都有所应用,在一般情况下,日志子系统的使用者希望的都是一个单一的方法,传入日志内容和日志类型,而日志系统会根据具体情况来进行写日志动作。对于日志系统的设计者来说,写一条日志可能需要包含一系列的工作,而日志系统决定把这些工作进行恰当的分派,这时就需要使用一个委托成员。下面代码展示了这个日志系统的简单实现方式。
在上述代码所示的Log子系统中,使用了一个Log类型的委托来做所有的日志工作,而LogManager只需要管理这个委托,负责分派任务即可。代码中初始化委托成员的过程即是任务分派的过程,读者可能已经注意到,LogManager的UseUTCTime和UseLocalTime方法都对委托成员进行了重新分配,这可以理解为任务的再分配。
说明
委托作为日志子系统的另一优点就在于可以灵活地分派任务,并且随时可以重新整理。读者可以尝试为LogManager添加其他功能,例如尝试提供其他编码的日志,并且提供重分配的公共方法来让使用者进行选择。
下面是以上代码执行后的日志输出:
答案
委托的应用场合通常是任务的执行者把细节工作进行再分配,执行者确切地知道什么工作将要被执行,但却把执行细节委托给其他组件、方法或者程序集。
委托的功能和其名字非常类似,在设计中其思想在于把工作委派给其他特定的类型或者组件。委托的使用者可以理解为工作的分派者,在通常情况下使用者清楚地知道哪些工作需要执行、执行的结果又是什么,但是他却不会亲自地去做这些工作,而是恰当地把这些工作分派出去。
在本节中,笔者将举一个日志读写的例子,来说明委托的实际应用。日志子系统在几乎所有的系统中都有所应用,在一般情况下,日志子系统的使用者希望的都是一个单一的方法,传入日志内容和日志类型,而日志系统会根据具体情况来进行写日志动作。对于日志系统的设计者来说,写一条日志可能需要包含一系列的工作,而日志系统决定把这些工作进行恰当的分派,这时就需要使用一个委托成员。下面代码展示了这个日志系统的简单实现方式。
using System; using System.IO; using System.Text; namespace Test { /// <summary> /// Log的类别 /// </summary> public enum LogType { Debug, Trace, Info, Warn, Error, } /// <summary> /// Log委托类型,由日志使用者直接执行来完成写日志的工作 /// </summary> /// <param name="content"></param> /// <param name="type"></param> public delegate void Log(string content,LogType type); public sealed partial class LogManager:IDisposable { //书写日志的组件 private Type _componentType; //日志文件 private string _logFile; //日志文件读写流 private FileStream _fs; //用来写日志的委托 public Log writeLog; //锁 private static object mutext = new object(); public LogManager() { writeLog = new Log(PreppareLogFile); writeLog += OpenStream; writeLog += AppendLocalTime; writeLog += AppendSeperator; writeLog += AppendComponentType; writeLog += AppendSeperator; writeLog += AppendType; writeLog += AppendSeperator; writeLog += AppendContent; writeLog += AppendNewLine; writeLog += CloseStream; } /// <summary> /// 构造方法 /// </summary> /// <param name="type">使用该日志的类型</param> /// <param name="file">日志文件全路径</param> public LogManager(Type type, string file) : this() { _logFile = file; _componentType = type; } /// <summary> /// 释放FileStream对象 /// </summary> public void Dispose() { if (_fs!=null) { _fs.Dispose(); } GC.SuppressFinalize(this); } ~LogManager() { if (_fs!=null) { _fs.Dispose(); } } #region 和日志文件有关的操作 /// <summary> /// 如果日志文件不存在,则新建日志文件 /// </summary> private void PreppareLogFile(string content, LogType type) { //只允许单线程创建日志文件 lock (mutext) { if (File.Exists(_logFile)==false) { using (FileStream fs = File.Create(_logFile)) { } } } } /// <summary> /// 打开文件流 /// </summary> private void OpenStream(string content, LogType type) { _fs = File.Open(_logFile, FileMode.Append); } /// <summary> /// 关闭文件流 /// </summary> private void CloseStream(string content, LogType type) { _fs.Close(); _fs.Dispose(); } #endregion #region 和时间记录有关的操作 /// <summary> /// 为日志添加当前UTC时间 /// </summary> private void AppendUTCTime(string content, LogType type) { //得到当前UTC时间 string time = DateTime.Now.ToUniversalTime().ToString(); byte[] con = Encoding.Default.GetBytes(time); _fs.Write(con, 0, con.Length); } /// <summary> /// 为日志添加本地时间 /// </summary> private void AppendLocalTime(string content, LogType type) { //得到本地时间 string time = DateTime.Now.ToLocalTime().ToString(); byte[] con = Encoding.Default.GetBytes(time); _fs.Write(con, 0, con.Length); } #endregion #region 和日志内容有关的操作 /// <summary> /// 添加日志内容 /// </summary> private void AppendContent(string content, LogType type) { byte[] con = Encoding.Default.GetBytes(content); _fs.Write(con, 0, con.Length); } /// <summary> /// 为日志添加组件类型 /// </summary> private void AppendComponentType(string content, LogType type) { byte[] con = Encoding.Default.GetBytes(_componentType.ToString()); _fs.Write(con, 0, con.Length); } /// <summary> /// 添加日志类型 /// </summary> private void AppendType(string content, LogType type) { string typeString = string.Empty; switch (type) { //针对不同的日志类型来记录 case LogType.Debug: typeString = "Debug"; break; case LogType.Trace: typeString = "Trace"; break; case LogType.Info: typeString = "Info"; break; case LogType.Warn: typeString = "Warn"; break; case LogType.Error: typeString = "Error"; break; default: typeString = ""; break; } byte[] con = Encoding.Default.GetBytes(typeString); _fs.Write(con, 0, con.Length); } #endregion #region 和日志格式控制有关的操作 /// <summary> /// 添加分隔符 /// </summary> private void AppendSeperator(string content, LogType type) { byte[] con = Encoding.Default.GetBytes(" | "); _fs.Write(con, 0, con.Length); } /// <summary> /// 添加换行符 /// </summary> private void AppendNewLine(string content, LogType type) { byte[] con = Encoding.Default.GetBytes("\r\n"); _fs.Write(con, 0, con.Length); } #endregion #region 修改所使用的时间类型 /// <summary> /// 设置使用UTC时间 /// </summary> public void UseUTCTime() { writeLog = new Log(PreppareLogFile); writeLog += OpenStream; //这里添加记录UTC时间的方法 writeLog += AppendUTCTime; writeLog += AppendSeperator; writeLog += AppendComponentType; writeLog += AppendSeperator; writeLog += AppendType; writeLog += AppendSeperator; writeLog += AppendContent; writeLog += AppendNewLine; writeLog += CloseStream; } /// <summary> /// 设置使用本地时间 /// </summary> public void UseLocalTime() { writeLog = new Log(PreppareLogFile); writeLog += OpenStream; //这里添加记录本地时间的方法 writeLog += AppendLocalTime; writeLog += AppendSeperator; writeLog += AppendComponentType; writeLog += AppendSeperator; writeLog += AppendType; writeLog += AppendSeperator; writeLog += AppendContent; writeLog += AppendNewLine; writeLog += CloseStream; } #endregion } class UseLog { /// <summary> /// 使用日志管理类型来记录日志 /// </summary> static void Main() { //使用日志 using (LogManager logManager = new LogManager(Type.GetType("Test.UseLog"), @"D:\TestLog.txt")) { //记录日志 logManager.writeLog("新建了日志", LogType.Debug); logManager.writeLog("写数据", LogType.Debug); logManager.UseUTCTime(); logManager.writeLog("现在是UTC时间", LogType.Debug); logManager.UseLocalTime(); logManager.writeLog("现在是本地时间", LogType.Debug); logManager.writeLog("发生错误", LogType.Error); logManager.writeLog("准备退出", LogType.Info); } } } }
在上述代码所示的Log子系统中,使用了一个Log类型的委托来做所有的日志工作,而LogManager只需要管理这个委托,负责分派任务即可。代码中初始化委托成员的过程即是任务分派的过程,读者可能已经注意到,LogManager的UseUTCTime和UseLocalTime方法都对委托成员进行了重新分配,这可以理解为任务的再分配。
说明
委托作为日志子系统的另一优点就在于可以灵活地分派任务,并且随时可以重新整理。读者可以尝试为LogManager添加其他功能,例如尝试提供其他编码的日志,并且提供重分配的公共方法来让使用者进行选择。
下面是以上代码执行后的日志输出:
答案
委托的应用场合通常是任务的执行者把细节工作进行再分配,执行者确切地知道什么工作将要被执行,但却把执行细节委托给其他组件、方法或者程序集。
相关文章推荐
- 哪些IT、信息技术可以应用到医疗行业中来?
- 地图开发应用可以与哪些移动应用结合?——地图应用产品定制
- 2018,人工智能可以在哪些领域最快得到应用和普及?
- 浅谈GIS可以应用在哪些领域
- MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些?
- MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些?
- Win10正式版哪些预装的应用可以卸载?Win10释放空间的详细教程
- 应用内切换主题有哪些方案可以实现
- 绿色IE 可以带来哪些实际应用?
- MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些?
- 生成式对抗网络GAN有哪些最新的发展,可以实际应用到哪些场景中
- unix域套接口可以用于哪些场合
- (一)委托模式简介 委托模式是基本的设计模式之一。委托,即是让另一个对象帮你做事情。 许多其他的模式,如状态模式、策略模式、访问者模式本质上是在更特殊的场合采用了委托模式。 委托模式使得我们可以用聚合
- 汇道科技:PHP编程语言可以应用在哪些方面?
- 应用内切换主题有哪些方案可以实现
- MySQL存储引擎通常有哪3种?各自分别有什么特点?应用场景是哪些?
- 应用内切换主题有哪些方案可以实现
- 应用消息队列设计可以解决哪些实际问题?
- 哪些IT、信息技术可以应用到医疗行业中来?
- win10 mobile 10066可以安装哪些apk应用软件?