• 软件测试技术
  • 软件测试博客
  • 软件测试视频
  • 开源软件测试技术
  • 软件测试论坛
  • 软件测试沙龙
  • 软件测试资料下载
  • 软件测试杂志
  • 软件测试人才招聘
    暂时没有公告

字号: | 推荐给好友 上一篇 | 下一篇

3. AopProxyAttribute AOP代理特性

发布: 2007-7-01 11:09 | 作者: admin | 来源: | 查看: 12次 | 进入软件测试论坛讨论

领测软件测试网   很多情况下,我们需要一个Singleton窗体,比如,任务管理器就可以是windows应用系统中的一个Singleton,于是我们这样做:在窗体类的实现中添加一个静态指向单件的成员,提供一个静态的CreateInstance方法,当第一次调用此方法时创建单件。另外还要处理Closing事件,以使点击窗体右上角的“×”时,隐藏窗体。每次需要实现一个单件窗体时都要这么做,于是我决定写一个基类ISingletonDisplayer,一个窗体不用作任何改变,只需要将原来的基类Form改为ISingletonDisplayer就变成一个Singleton窗体,这就很方便了。先给出在VS2003中的实现。

public class ISingletonDisplayer : Form  //从Form继承
 {
  private static ISingletonDisplayer singleton = null ;
  private static bool toClean = false ;

  protected ISingletonDisplayer()
  {
   this.Closing += new System.ComponentModel.CancelEventHandler(ISingletonDisplayer_Closing);
  }

  #region static for singleton

  #region GetSingleton
  public static ISingletonDisplayer GetSingleton()
  {
   if(ISingletonDisplayer.singleton != null)
   {
    ISingletonDisplayer.singleton.Visible = true ;
   }
   return ISingletonDisplayer.singleton ;
  }

  #endregion

  #region ReCreateSingleton

  //formOnUI存在是因为窗体只能在主线程(UI线程)中创建。
  public static void ReCreateSingleton(Type targetType ,object[] args , Form formOnUI)
  {
   Type supType = typeof(ISingletonDisplayer) ;
   if(! supType.IsAssignableFrom(targetType))
   {
    throw new Exception("Target type is not derived from ISingletonDisplayer !") ;
   }

   if(formOnUI.InvokeRequired)
   {
    object[] paras = {targetType ,args ,formOnUI} ;
    formOnUI.Invoke(new CBackCreateForm(ISingletonDisplayer.ReCreateSingleton) ,paras) ;
   }
   else
   {
    try
    {
     ISingletonDisplayer.toClean = false ;
     ISingletonDisplayer.singleton  = (ISingletonDisplayer)Activator.CreateInstance(targetType ,args) ;
     ISingletonDisplayer.singleton.Visible = false ;
    }
    catch(Exception ee)
    {
     throw ee ;
    }
   }
  }
  #endregion

  #region DestroySingleton
  public static void DestroySingleton()
  {
   ISingletonDisplayer.toClean = true ;
   if(ISingletonDisplayer.singleton != null)
   {
    ISingletonDisplayer.singleton.Close() ;
    ISingletonDisplayer.singleton = null ;
   }
  }
  #endregion

  #endregion

  #region ISingletonDisplayer_Closing
  private void ISingletonDisplayer_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  {
   if(! ISingletonDisplayer.toClean)
   {
    this.Visible = false ;
    e.Cancel = true ;
    return ;
   }
  }
  #endregion
 }

 internal delegate void CBackCreateForm(Type targetType ,object[] args  , Form formOnUI) ;

  * 使用方法:
  * 如果一个Displayer需要以Singleton模式呈现,那么可以先以常规的方式设计Displayer,设计过程中不需要涉及任何与单件
  * 相关的东西。设计完后,只要将Displayer的基类由Form改为ISingletonDisplayer即可。接下来即可以单件的模式使用Displayer了。
  *
  * 如:
  * public class AppServersInfoForm2 : ISingletonDisplayer{}
  * object[] args = {obj} ;
  * ISingletonDisplayer.ReCreateSingleton(typeof(AppServersInfoForm2) ,args ,formOnUI) ;
    
 

上面的实现很容易理解,但是上面的实现有一个弊病,因为所有的单件窗体都要公用一个静态的ISingletonDisplayer singleton 成员,所以一个应用程序中只能有一个单件继承自ISingletonDisplayer。/ 在VS2005中可以使用泛型突破此限制。 

下面在看看在VS2005中的实现。

 public class ISingletonDisplayer<T> : Form
 {
  private static ISingletonDisplayer<T> singleton = null ;
  private static bool toClean = false ;

  protected ISingletonDisplayer()
  {
   this.Closing += new System.ComponentModel.CancelEventHandler(ISingletonDisplayer_Closing);
  }

  public static ISingletonDisplayer<T> GetSingleton()
  {
   if(ISingletonDisplayer<T>.singleton != null)
   {
    ISingletonDisplayer<T>.singleton.Visible = true ;
   }
   return ISingletonDisplayer<T>.singleton ;
  }

  public static void ReCreateSingleton(Type targetType ,object[] args , Form formOnUI)
  {
   Type supType = typeof(ISingletonDisplayer) ;
   if(! supType.IsAssignableFrom(targetType))
   {
    throw new Exception("Target type is not derived from ISingletonDisplayer<T> !") ;
   }

   if(formOnUI.InvokeRequired)
   {
    object[] paras = {targetType ,args ,formOnUI} ;
    formOnUI.Invoke(new CBackCreateForm(ISingletonDisplayer<T>.ReCreateSingleton) ,paras) ;
   }
   else
   {
    try
    {
     ISingletonDisplayer<T>.toClean = false ;
     ISingletonDisplayer<T>.singleton  = (ISingletonDisplayer<T>)Activator.CreateInstance(targetType ,args) ;
     ISingletonDisplayer<T>.singleton.Visible = false ;
    }
    catch(Exception ee)
    {
     throw ee ;
    }
   }
  }

  public static void DestroySingleton()
  {
   ISingletonDisplayer<T>.toClean = true ;
   if(ISingletonDisplayer<T>.singleton != null)
   {
    ISingletonDisplayer<T>.singleton.Close() ;
    ISingletonDisplayer<T>.singleton = null ;
   }
  } 
  
  private void ISingletonDisplayer_Closing(object sender, System.ComponentModel.CancelEventArgs e)
  {
   if(! ISingletonDisplayer<T>.toClean)
   {
    this.Visible = false ;
    e.Cancel = true ;
    return ;
   }
  }
 
    }
 

    internal delegate void CBackCreateForm(Type targetType ,object[] args  , Form formOnUI) ;

    如:
    public class AppServersInfoForm2 : ISingletonDisplayer<AppServersInfoForm2>{}
    object[] args = {obj} ;
    ISingletonDisplayer<AppServersInfoForm2>.ReCreateSingleton(typeof(AppServersInfoForm2) ,args ,this) ;

这样每个单件都有自己的静态实例,就不会相互干扰了。

如果你有更好的实现方法,欢迎和我讨论


延伸阅读

文章来源于领测软件测试网 https://www.ltesting.net/


关于领测软件测试网 | 领测软件测试网合作伙伴 | 广告服务 | 投稿指南 | 联系我们 | 网站地图 | 友情链接
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备2023014753号-2
技术支持和业务联系:info@testage.com.cn 电话:010-51297073

软件测试 | 领测国际ISTQBISTQB官网TMMiTMMi认证国际软件测试工程师认证领测软件测试网