哪种方法适合辛格尔顿
本文关键字:方法 | 更新日期: 2023-09-27 17:59:50
我的程序用命令行中传递的参数实例化一个对象。我需要能够用这些参数实例化一个对象,但它应该只创建一次。我读过这些帖子1&2但我仍然不明白哪种方法更好:
1 - var myInstance = MyClass.Instance.Create("param1", "param2");
或
2 - var myInstance = MyClass.Instance;
myInstance.setParam1("param1");
myInstance.setParam2("param2");
在第一种方法中,将为传递给Create
的每个不同参数对创建新实例。防止这种情况发生的唯一方法是在Create
内部设置标志,该标志将返回创建的实例。
在第二种方法中,问题是如果MyClass
的构造函数将依赖于param1
和param2
呢?
那么,你有什么建议?
您也可以使用第一种方法:
MyClass.Instance.Create("param1", "param2")
略有不同,这可能会使参数不是强制性的,如果你需要的话,使用命名参数,比如:
MyClass.Instance.Create(param1 = "param1", param2 = "param2")
因此,您可以完全避免使用参数(在调用期间),并使用声明中提供的默认值。
我会:
- 使用接受参数的公共构造函数创建一个不可变的
Config
类 -
创建一个静态方法
Config ParseCommandLine(string)
,将命令行转换为Config
对象。由于这是一个纯函数(没有副作用,没有全局状态),因此测试它很容易。
- 一个静态方法
Config ParseCommandLine()
,它获取实际的命令行并调用上面的方法(有点难看,因为它访问全局可变状态) - 最后使用
Config.SetInstance(ParseCommandLine())
来支持"singleton"上的Instance
属性。这有点难看,但使用singleton一开始就很难看
这个"singleton"并没有真正强制要求有一个配置,但它更像是一个默认实例。根据我的经验,很少需要真正的单身汉,甚至默认实例也有点像黑客。
你最终会得到这样的东西:
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
属性,将配置注入到需要它的对象中。但对于一个可能过于工程化的小程序来说。
在您的情况下,最好不要使用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;
}
}