使用参数执行单例的更紧凑的方法

时间:2011-01-24 18:00:57

标签: c# singleton

我对模式并不擅长。 (但我确实意识到它们非常重要。)我有一个需要单例的场景,但也需要一个参数。通常对于单身人士我只做一个静态方法:

return _instance ?? (_instance = new SingletonClass()); 

但是当涉及参数时,你必须每次都要传递参数来访问事物(以防万一你正在进行构建的时间)或者像我在这里做的那样:

public class PublicFacingSingleton
{
    private readonly string _paramForSingleton;
    public PublicFacingSingleton(string paramForSingleton)
    {
        _paramForSingleton = paramForSingleton;
    }

    private PrivateFacingSingleton _access;
    public PrivateFacingSingleton Access
    {
        get 
        { 
            // If null then make one, else return the one we have.
            return _access ?? 
                   (_access = new PrivateFacingSingleton(_paramForSingleton)); 
        }
    }
}

public class PrivateFacingSingleton
{
    private readonly ClassWithOnlyOneInstance _singleInstance;
    public PrivateFacingSingleton(string paramForSingleton)
    {
        _singleInstance = new ClassWithOnlyOneInstance(paramForSingleton);
    }

    public WorkItem ActualMethodToDoWork()
    {
        return _singleInstance.UseTheClass();
    }
}

然后创建PublicFacingSigleton并使用它。例如:

var publicFacingSingleton = new PublicFacingSingleton("MyParameter")
publicFacingSingleton.Access.ActualMethodToDoWork();

这有几个问题。其中一些是:

  1. 我现在有两个班,而不是一个
  2. 不知情的开发人员仍然可以轻松创建PrivateFacingSingleton实例。
  3. 有没有更好的方式来解决我的问题,但每次我想打电话ActualMethodToDoWork()时都没有让我传递参数(即publicFacingSingleton.Access("MyParameter").ActualMethodToDoWork()

    注意:上面的代码是从我的实际代码中获取的示例。如果您想查看我的实际代码,请here

2 个答案:

答案 0 :(得分:2)

这可能被认为不是解决方案,但我认为应该在这里提及:

当单身人士需要参数时,它可能不是单身人士。

您可能需要使用参数的其他值(现在或长期)创建的实例

答案 1 :(得分:1)

也许单身和工厂模式的组合可以满足您的需求? 可以在单例类中放置多个函数,这些函数仅实例化一次。同时,单例类充当工厂,提供所需的输出,并充当创建逻辑的抽象。

public class Singleton {

    private static final Singleton INSTANCE = new Singleton();
    private Object FactoryOutput;
    // Private constructor prevents instantiation from other classes
    private Singleton() {
    }

    public static Singleton getInstance() {
        return INSTANCE;
    }
    public Object SomeClassWhichNeedsSingleInstantiation(Object Parameter) 
    {
    If(FactoryOutput == null)
      { 
      FactoryOutput = new FactoryOutput(Parameter);
      }
    return FactoryOutput;    
    } 
}