Fork me on GitHub
简单工厂模式

   简单工厂模式Simple Factory根据提供给它的数据,返回一个类的实例。通常它返回的类都有一个公共的父类(或者接口对象)。

简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。如数据库生产工厂就是简单工厂的一个应用。
         采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;缺点是可实例化的类型在编译期间已经被确定,如果增加新类 型,则需要修改工厂,不符合OCP(开闭原则)的原则。简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。

下面是我实例中的类结构图,它有一个ICreate的公共接口,有一个方法叫Create,返回值为Void

其中公用的接口代码如下:(最后工厂的返回值类型)

复制代码
1    /// <summary>
2         /// 简单工厂接口,返回值类型
3         /// </summary>
4         public interface ICreate
5         {
6             void Create();
7         }
复制代码

而下面,分别用people和animal两个类去实现了ICreate接口,并实现了它的Create方法。

复制代码
 1      /// <summary>
 2         /// 人类实现工厂接口
 3         /// </summary>
 4         public class People : ICreate
 5         {
 6 
 7             #region ICreate 成员
 8 
 9             public void Create()
10             {
11                 Console.WriteLine("创建人类");
12             }
13 
14             #endregion
15         }
16         /// <summary>
17         /// 动物实现工厂接口
18         /// </summary>
19         public class Animal : ICreate
20         {
21 
22             #region ICreate 成员
23 
24             public void Create()
25             {
26                 Console.WriteLine("创建动物");
27             }
28 
29             #endregion
30         }
复制代码

而对于外界来说,会有另一个类去为外界提供服务,它们可以需要建立People或者Animal类型的实现,代码如下:

复制代码
 1     public class CreateFactory
 2         {
 3             public static ICreate GeneratorCreate(string createName) { 
 4             switch (createName)
 5             {
 6                 case "People":
 7                     return new People();                   
 8                 case "Animal":
 9                     return new Animal();
10                 default:
11                     throw new NotImplementedException();                   
12             }
13         }
复制代码

最后,在使用它时,直接使用CreateFactory.GeneratorCreate("类型条件名")即可生成你的类对象了。

单件模式(Singleton)要求一个类有且仅有一个实例,并且提供了一个全局的访问点。

从概念上来研究一下它的实现,不考虑纯种安全

复制代码
 1 public sealed class Singlton
 2 {
 3     static Singlton instance = null;
 4     private Singlton() { }
 6  
 7     public static Singlton Instance
 8     {
 9         get
10         {
11             if (instance == null)
12             {
13                 return new Singlton();
14             }
15             return instance;
16         }   
17     }   
18 }
复制代码

上面的实现方式,对于多线程会有问题,因为Singlton 对象可能不指一次被创建,而罪魁祸首就是if (instance == null)这句话,它并不是线程安全的。

如果希望实现线程安全的单件,我们最先想到的应该就是借助lock机制来实现,代码可能是这样:

复制代码
 1 public sealed class Singlton
 2 {
 3     static Singlton instance = null;
 4  
 5     static readonly object o = new object();
 6  
 7     Singlton()
 8     { }
 9  
10     public static Singlton Instance
11     {
12         get
13         {
14             lock (o)
15             {
16                 if (instance == null)
17                 {
18                     return new Singlton();
19                 }
20                 return instance;
21             }
22         }   
23     }   
24 }
复制代码

而我们使用静态对象在静态结构方法里为它进行初始化,这种方式也非常在程序中看到,如:

复制代码
 1 public sealed class Singlton
 2 {
 3     static readonly Singlton instance = null;
 4  
 5     static Singlton()
 6     { instance = new Singlton();}
 7  
 8     public static Singlton Instance
 9     {
10         get
11         {
12             return instance;
13         }
14     }
15 }
复制代码

这种方法及其它单件模式有一个问题,就是如果希望去更新单件对象的值,是无法实现的,比如,instance对象希望从数据库中取出一个列表,而列表的信息有可能

发生变化,怎样保证instance里取的是最新的信息呢,这样我们可以在单件中引入时间触发器的概念,代码如下:

复制代码
 1     public class CategoryRepository : Car_RentalRepositoryBase, ICategoryRepository
 2     {
 3         #region 静态树结构,每1分钟去获一下数据库
 4         static List<Category> categoryList = null;
 5         /// <summary>
 6         /// 数据实体
 7         /// </summary>
 8         public static volatile List<Category> Instance = null;
 9         static CategoryRepository categoryRepository = new CategoryRepository();
10         static System.Timers.Timer sysTimer = new System.Timers.Timer(600000);
11         static CategoryRepository()
12         {
13             Reload();//第一次加载
14             sysTimer.AutoReset = true;
15             sysTimer.Enabled = true;
16             sysTimer.Elapsed += new System.Timers.ElapsedEventHandler(sysTimer_Elapsed);
17             sysTimer.Start();
18         }
19 
20         /// <summary>
21         /// 被订阅了Elapsed事件的方法,每隔一段时间去重新获取数据列表
22         /// </summary>
23         /// <param name="sender"></param>
24         /// <param name="e"></param>
25         static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
26         {
27             Reload();
28         }
29 
30         internal static void Reload()
31         {
32             categoryList = categoryRepository.GetModel().OrderBy(i => i.SortNumber).ToList();
33             Instance = categoryList.Where(i => i.ID != 1).ToList();
34         }
35 }
复制代码

这种方式解决了实例不能获取最新的问题。

最后,奉献出国外牛人写了的泛型单件类,如果实现的类直接继承它即可。

复制代码
 1  /// <summary>
 2     /// 泛型单例基类
 3     /// </summary>
 4     public abstract class Singleton<TEntity> where TEntity : class
 5     {
 6         private static readonly Lazy<TEntity> _instance
 7           = new Lazy<TEntity>(() =>
 8           {
 9               var ctors = typeof(TEntity).GetConstructors(
10                   BindingFlags.Instance
11                   | BindingFlags.NonPublic
12                   | BindingFlags.Public);
13               if (ctors.Count() != 1)
14                   throw new InvalidOperationException(String.Format("Type {0} must have exactly one constructor.", typeof(TEntity)));
15               var ctor = ctors.SingleOrDefault(c => c.GetParameters().Count() == 0 && c.IsPrivate);
16               if (ctor == null)
17                   throw new InvalidOperationException(String.Format("The constructor for {0} must be private and take no parameters.", typeof(TEntity)));
18               return (TEntity)ctor.Invoke(null);
19           });
20 
21         public static TEntity Instance
22         {
23             get { return _instance.Value; }
24         }
25     }
复制代码

感谢您好阅读,希望本文章对您有帮助。

相关链接:基础才是重中之重~延迟初始化

参考 文献:

http://technet.microsoft.com/zh-cn/magazine/dd997286%28VS.95%29.aspx

http://www.fascinatedwithsoftware.com/blog/post/2011/07/13/A-Generic-Singleton-Class.aspx

 

说说设计模式~目录

 说说设计模式~单件模式

 说说设计模式~简单工厂模式

 

 

 

posted on 2012-06-24 22:58  HackerVirus  阅读(173)  评论(0编辑  收藏  举报