在抽象工厂方法中调用单例类

时间:2018-05-24 06:30:34

标签: c# .net design-patterns c#-4.0

我有一个抽象工厂方法的类如下:

 public abstract class OpClass
    {
        public abstract IHou OperationInvoke(string opClass);
    }

    public class FactoryClass : OpClass
    {
        public override IHou OperationInvoke(string opClass)
        {
            if(opClass == "T")
            {
                //new Treasure();
            }

        }
    }

和混凝土" Treasure"上课是这样的:

 public interface IHou
    {
        void Operation(Player p, List<Player> lstPlayers);
    }

public sealed class Treasure : IHou
    {
        private static Treasure instance = null;
        private static readonly object padlock = new object();

        Treasure()
        {

        }

        public static Treasure Instance
        {
            get
            {
                lock (padlock)
                {
                    if (instance == null)
                    {
                        instance = new Treasure();
                    }
                    return instance;
                }
            }
        }

        public void Operation(Player p, List<Player> lstPlayers)
        {
            p.Points = p.Points + 200;

        }
    }

在我的主要方法中,我试图将其称为:

Main()
{
    Player p = //Populate from db;
    List<Player> players = //populate from db 
    OpClass c = new FactoryClass();
    IHou output = c.OperationInvoke("T");
    output.Operation(p, players);
}

但我需要一个&#34; Treasure&#34; 类的单个实例,所以我想改变正常的&#34; Treasure&#34; 类到单例类。

因此,在这种情况下,如何创建Treasure类的单个实例并保留facory模式?如果不能实现最佳解决方案,如果增加具体类的数量,如Treasure,House,Blocks等?

编辑:在这里使用工厂模式是不合适的,因为我的理解是,如果我们有许多具有常见行为的课程,比如在这个宝藏中,再说一个课程&#34; &#34;添加以不同的方式计算点数,我将允许工厂决定调用哪一个实例化。

2 个答案:

答案 0 :(得分:1)

您可以使用Flyweight模式,在此模式中,您将实例存储在缓存或字典中并从工厂返回

在以下基于泛型的工厂实现的帮助下,您不需要添加更多案例,它将基于模板类型T创建类。您可以访问下面的文章链接具有相同的实现之王。

public class FlyWeidhtFactory
{
    Dictionary<string,IHou> dic = new Dictionary<string,IHou>();

    public IHou OperationInvoke<T>(string opClass)  where T: IHou 
    {
        Type type = typeof(T);
        string fullname = type.FullName;
        if(!dic.Contains(fullname)
        {
           Object obj = Activator.CreateInstance(type);
           dic[fullname] = (T)obj;  
           //no need of more cases 
        }
        return dic[opClass]; 
    }
}

模式确保您将创建许多对象,并且通过上面的实现,您确信将只创建一个类的实例。没有必要去单身模式。

制作具体的课程internal sealed,以便在你的装配之外不会显示。

以上只是基于您的问题的建议。

工厂和轻量级的文章:

答案 1 :(得分:0)

只需在工厂中返回单例实例。

您的工厂有责任了解如何制作&#39;。在Treasure的情况下,只有一个实例,因此工厂只返回它。

基于密钥返回共享或非共享实例的事实使您的代码类似于flyweight。如果没有其他代码需要在工厂外创建Treasure,那么您不需要Singleton。您可以通过将它们作为工厂的嵌套类来强制通过工厂实例化类。

因此,使用私有构造函数使Treasure成为工厂的嵌套类。或者使它成为一个私有嵌套类,并使用工厂方法返回一个抽象基础。