C# 单例还是静态-我应该使用什么?
我不知道该用什么。我有三节课<代码>密码服务,C# 单例还是静态-我应该使用什么?,c#,C#,我不知道该用什么。我有三节课密码服务,设置服务,文件服务。这些类每个包含大约2个方法。这些方法正在更多的程序集中使用。现在我把它当作一个单身汉。但我不确定我是否应该。我认为一个静态类就足够了。 你觉得怎么样 代码: public class PasswordService { private PasswordService(){} private static PasswordService _instance; public static PasswordServ
设置服务
,文件服务
。这些类每个包含大约2个方法。这些方法正在更多的程序集中使用。现在我把它当作一个单身汉。但我不确定我是否应该。我认为一个静态类就足够了。
你觉得怎么样
代码:
public class PasswordService
{
private PasswordService(){}
private static PasswordService _instance;
public static PasswordService Instance
{
get { return _instance ?? (_instance = new PasswordService()); }
}
public byte[] EncryptPassword(string password)
{
var protectedPass = Encoding.UTF8.GetBytes(password);
return ProtectedData.Protect(protectedPass, null);
}
public string DecryptPassword(byte[] encryptedPassword)
{
var unprotectedPass = ProtectedData.Unprotect(encryptedPassword, null);
return Encoding.UTF8.GetString(unprotectedPass, 0, unprotectedPass.Length);
}
}
1-为这些服务创建一个单例是正确的,因为它们似乎要处理一个特定的任务
2-尽可能避免静态,因为如果您使用TDD并使用Contineus Integration server进行自动单元测试,您将无法有效地模拟静态。1-为这些服务创建单例是正确的,因为这些服务似乎要处理一个特定的任务
2-尽可能避免静态,因为如果使用TDD并使用Contineus Integration server进行自动单元测试,则无法有效地模拟静态。我建议您保留单例,除非您使用的是实例或DI。单例可以很容易地重构为实例,而静态类必须重新实现为非静态类。此外,您可以用测试假人替换实例,而替换静态实现几乎是不可能的 例如,您可能会遇到这样一种情况:对于两个不同的配置文件,您的程序必须处理多个
FileConfiguration
实例。可以将单个实例拆分为两个实例池
我遇到这个问题时使用了一个DAO类,该类过去是静态的,能够连接到一个DB。我们必须重构它,因为新的需求包括在一个程序实例中支持n>1个数据库
正如Mikhail指出的,只对真正无状态的东西使用静态。静态字段中的配置文件或所选密码散列算法已经是一种状态,上面示例中的连接字符串也是-即使它们在运行时可能永远不会更改。我建议您保留单例,除非您使用的是实例或DI。单例可以很容易地重构为实例,而静态类必须重新实现为非静态类。此外,您可以用测试假人替换实例,而替换静态实现几乎是不可能的 例如,您可能会遇到这样一种情况:对于两个不同的配置文件,您的程序必须处理多个
FileConfiguration
实例。可以将单个实例拆分为两个实例池
我遇到这个问题时使用了一个DAO类,该类过去是静态的,能够连接到一个DB。我们必须重构它,因为新的需求包括在一个程序实例中支持n>1个数据库
正如Mikhail指出的,只对真正无状态的东西使用静态。静态字段中的配置文件或所选密码散列算法已经是一种状态,上面示例中的连接字符串也是-即使它们在运行时可能永远不会更改。您的类中没有任何状态,所以我看不出有任何理由使用类的实例。
我建议您使用静态类。您的类中没有任何状态,所以我看不出有任何理由使用类的实例。
我建议您使用静态类。这个问题的答案总是一样的:这取决于情况。我想说的是,单例几乎总是邪恶的。使用每个服务的一个实例。你最终会得到一个更灵活的设计,在那里你可以看到你真正的依赖关系。@SoMoS:你本质上是说“单身是邪恶的,所以使用他们”。或者你想说“在你想使用这些服务的任何地方创建一个新实例”@Nuffin:对不起,我的意思当然是“在你需要的任何地方创建一个新实例”。如果多个对象必须共享同一个实例,则将其作为参数传递给构造函数,或以最适合设计的方式传递。这个问题的答案总是一样的:这取决于。可能的重复我会说,单例几乎总是邪恶的。使用每个服务的一个实例。你最终会得到一个更灵活的设计,在那里你可以看到你真正的依赖关系。@SoMoS:你本质上是说“单身是邪恶的,所以使用他们”。或者你想说“在你想使用这些服务的任何地方创建一个新实例”@Nuffin:对不起,我的意思当然是“在你需要的任何地方创建一个新实例”。如果多个对象必须共享同一个实例,则将其作为构造函数上的参数传递,或者以最适合设计的方式传递。因此,它可以是单例,或者我应该将其重新创建为静态?因此,它可以是单例,或者我应该将其重新创建为静态?这些类中没有一个保持任何状态。中只有方法。这些类中没有一个保持任何状态。只有方法在里面。但我不认为,我保持任何状态。这些方法只返回结果。这些类没有任何字段。@JurajP至于
密码服务
你是对的,从技术上讲没有状态。但是,例如EncryptPassword
和DecryptPassword
是相互关联的,因为它们共享编码.UTF8
的使用。在这里以及您的其他服务中,这可能会变成一种类似于readonly Encoding enc=Encoding.UTF8
的状态,以便进行更简单、更不容易出错的重构。我承认这听起来很牵强,但我很后悔我过去做的一些静态方法,它们不是无状态的,在技术上彼此无关。希望我能很好地表达我的观点……:)但我不认为我保持了任何状态。这些方法只返回结果。这些类没有任何字段。@JurajP至于密码服务
你是对的,从技术上讲没有状态。但是,例如EncryptPassword
和DecryptPassword
是相互关联的,因为它们共享编码.UTF8
的使用。在这里和您的其他服务中,这可能会变成一种类似于代码的状态