0

我的程序使用命令行中传递的参数实例化一个对象。我需要能够使用这些参数实例化一个对象,但它应该只创建一次。我已经阅读了这些帖子12,但我仍然不明白哪种方法更好:

1 - var myInstance = MyClass.Instance.Create("param1", "param2");

或者

2 - var myInstance = MyClass.Instance;
    myInstance.setParam1("param1");
    myInstance.setParam2("param2");

在第一种方法中,Create将为传递给的每对不同参数创建新实例。防止这种情况的唯一方法是在内部设置标志Create,该标志将返回创建的实例。

在第二种方法中,问题是如果构造函数MyClass将取决于param1andparam2怎么办?

那么,你有什么建议?

4

3 回答 3

1

您也可以使用第一种方法:

MyClass.Instance.Create("param1", "param2")

略有不同,这可能会使参数不是强制性的,如果需要,使用Named Parameters,比如:

MyClass.Instance.Create(param1 = "param1", param2 = "param2")

因此,您可以完全避免使用参数(在调用期间)并使用声明中提供的默认值。

于 2013-02-17T16:50:49.147 回答
0

ID:

  • Config使用带有参数的公共构造函数创建一个不可变类
  • 创建一个Config ParseCommandLine(string)将命令行转换为Config对象的静态方法。

    由于这是一个纯函数(没有副作用,没有全局状态),因此很容易对其进行测试。

  • 获取实际命令行并调用上述方法的静态方法Config ParseCommandLine()(有点难看,因为它访问全局可变状态)
  • 最后用于Config.SetInstance(ParseCommandLine())支持Instance您的“单身人士”上的财产。这有点难看,但首先使用单例是难看的。

这个“单例”并没有真正强制要求只有一个配置,但它更像是一个默认实例。根据我的经验,很少需要真正的单例,即使是默认实例也是一种 hack。

你最终会得到这样的东西:

public class Config
{
    public string Param1{get;private set;}
    public int Param2(get;private set;}

    public Config(string param1, int param2)
    {
        Param1=param1;
        Param2=param2;
    }

    // take a string[] if you prefer to use Environment.GetCommandLineArgs
    public Config ParseCommandLine(string commandLine)
    {
        string param1=...;
        int param2=...;

        return new Config(param1:param1, param2:param2);
    }

    public Config ParseCommandLine()
    {
       return ParseCommandLine(Environment.CommandLine);
    }
}

我还考虑将静态Instance属性扔掉,转而将配置注入需要它的对象。但是对于一个可能过度工程的小程序。

于 2013-02-17T17:04:24.270 回答
0

在您的情况下,最好不要使用 Singleton。

单身人士的意图:

  • 确保只创建一个类的一个实例。
  • 提供对对象的全局访问点。

http://www.oodesign.com/singleton-pattern.html

如果您需要确保只允许一个实例,请使用私有静态属性作为标志。

更新:

public class MyClass {

    private static boolean isAlreadyInitiated = false;

    public MyClass() {
        if(isAlreadyInitiated){
            throw new IllegalStateException("Only one instance allowed.");
        }
        isAlreadyInitiated = true;
    }
}
于 2013-02-19T17:34:13.370 回答