让我们假设有一个像Person这样的类,它在一个Setting类中实现了一些默认设置。这些设置可能是“默认标题”或“需要名字”之类的内容。相应地,像Address类这样的其他类也可能有一些默认设置。 Setting类将每个设置保存到持久存储中。
是否应该在每个类中实现静态方法,例如包含这些设置的“SetDefaults()”,以便外部方法可以在每个对象类型上调用SetDefaults()?例如Person.SetDefaults()然后是Address.SetDefaults()?
或者有更好的面向对象的方式吗?
[更新:这不能在构造函数中,因为SetDefaults()应该在特定时间点从外部类调用,而不是每次构造对象时。]
答案 0 :(得分:3)
我无法想到默认情况下真正跨越的许多场合......考虑到对象可能经历的所有不同用例(尤其是反序列化之类的东西 - 这可能会最终设置默认值,即使这样不是预期的。)
这里有一个选择是IoC;像StructureMap这样的IoC容器能够在初始化之后设置属性,然后从调用代码中抽象出来。
另一个选项可能是某种模板实例(静态),实例可以复制值。但我认为这在几种情况下是有风险的。如果不同的线程(可能是Web服务器上的请求)需要不同的默认值,您也会遇到问题。 [ThreadStatic]
不是好的选项(虽然它是一个选项)。
另一个选项(提供最大的灵活性)是提供用户可设置的工厂......可能通过委托或事件机制 - 但我很难看到为什么你可能想要这个场景。这不是我经常看到的......
重新更新:如果它仅由外部类使用;它可能会使用类似扩展方法的东西(而不是Person
类必须知道任何关于此的内容):
public static class PersonExt {
public static void SetDefaults(this Person person) {
// your code
}
}
由于听起来原始Person
类并不关心SetDefaults
,因此这会使逻辑与Person
完全分开。
答案 1 :(得分:1)
为什么不在创建对象时(在构造函数中)设置这些默认值。 默认值是-imho-当没有为该属性赋予特定值时应该分配给属性的值,因此,我认为在创建对象时设置这些默认值是个好主意(在构造函数中,或通过工厂)。
或者,我错过了什么?
答案 2 :(得分:0)
我将它们放在构造函数中。
class Person
{
public Person()
{
this.Settings = MakeDefault();
}
public Person(Settings settings)
{
this.Settings = settings;
}
}
答案 3 :(得分:0)
您可以创建一个设置类来封装所有类(Person,Address)的设置。
您可以设置说人员的默认设置:
// Injected
Settings settings;
Setting personSetting = new ...;
...
settings.StoreSettingsFor(typeof(Person), personSettings);
答案 4 :(得分:0)
如果您愿意,也可以使用单例存储此数据,特别是如果从某个位置的存储中检索这些值,因为这会减少访问存储的次数。
(在这种情况下,存储可以是数据文件,注册表,数据库。)
答案 5 :(得分:-1)
您还可以实施Abstract factory pattern并使用您的设置配置工厂。或者,您也可以将IoC injecting dependency用于此工厂类。
Preson的简易工厂课程可以看看如下:
public class PersonFactory
{
private readonly ISettings settings;
public PersonFactory(ISettings settings)
{
this.settings = settings;
}
public Person Create()
{
Person p = new Person();
// ... you code for populating person's attributes form settings.
return p;
}
}