【问题标题】:Invoking a singleton class in a abstract factory method在抽象工厂方法中调用单例类
【发布时间】:2018-05-24 06:30:34
【问题描述】:

我有一个带有抽象工厂方法的类,如下所示:

 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);
}

但我需要一个 "Treasure" 类的单个实例,所以我想将普通的 "Treasure" 类更改为单例类。 p>

那么在这种情况下,我如何创建 Treasure 类的单个实例并保留工厂模式?如果添加了诸如 Treasure 、 House 、 Blocks 等具体类的数量,那么最好的解决方案是什么?

编辑:在这里使用工厂模式不合适吗,因为我的理解是,如果我们有很多具有共同行为的类,比如这个 Treasure,然后再说一个类“House”被添加,它以不同的方式计算点,我将允许工厂决定调用哪个实例化。

【问题讨论】:

  • 请注意,如果instance 为空,您应该检查锁外,否则您每次都必须锁定,即使您有实例,这意味着线程将必须争取一把锁。外面一张,里面一张。
  • 你可以使用 DI 容器吗?像这样的事情通常是 DI 容器的责任。任何 DI 容器都可以开箱即用地管理这个。
  • 你不需要工厂模式。当初始化实例所需的参数数量很大并且初始化不直接,或者当您在初始化和使用实例之间需要一些额外的逻辑时,使用工厂模式。你的Treasure 甚至不带一个参数...

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


【解决方案1】:

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

在基于泛型的工厂实现的帮助下,您不需要添加更多案例,它将基于模板类型 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]; 
    }
}

pattern 确保您将创建许多对象,并且通过上述实现,您可以确定您的类只会创建一个实例。无需选择单例模式。

创建你的具体类internal sealed,这样它就不会在你的程序集之外可见。

以上只是根据您的问题提出的建议。

工厂和享元的文章:

【讨论】:

    【解决方案2】:

    只需返回工厂中的单例实例即可。

    您的工厂有责任知道如何“制造”。在 Treasure 的情况下,只有一个实例,所以工厂只返回它。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-05
      • 2014-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      相关资源
      最近更新 更多