ISingletonDisplayer 单件模式显示器C#实现

        很多情况下,我们需要一个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) ;

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值