我在日常编码中发现了一种反复出现的模式,如下所示:
uniq
在这些情况下,绝对需要var foo = new Foo();
foo.Initialize(params);
foo.DoSomething();
,以便它实际上foo.Initialize
,否则某些DoSomething
属性仍然是foo
/未初始化。
它有一个模式吗?如何确保{/ 1>} null
之后只会/永远被称为?如果不这样做,如何继续:我应该提出异常,默认忽略它,检查一些标志......?
答案 0 :(得分:5)
基本上你说Initialize
是构造函数。所以代码真的应该是构造函数的一部分:
var foo = new Foo(params);
foo.DoSomething();
这正是构造函数的用途:它的代码可以保证在运行任何对象方法之前运行,它的工作是检查前置条件并提供一个理智的环境其他运行的对象方法。
答案 1 :(得分:2)
如果在初始化中确实存在很多的工作,那么我当然可以看到它在构造函数中放置太多的参数"#34 ;。 (我确信那些对语言机制有更深入了解的人可能会对此事提供一些令人信服的解释,但我不是那个人。)
听起来像工厂在这里很有用。像这样:
public class Foo
{
private Foo()
{
// trivial initialization operations
}
private void Initialize(SomeType params)
{
// non-trivial initialization operations
}
public static Foo CreateNew(SomeType params)
{
var result = new Foo();
result.Initialize(params);
return result;
}
}
消费代码变为:
var foo = Foo.CreateNew(params);
foo.DoSomething();
可以将所有形式的附加逻辑放入该工厂,包括params
的各种健全性检查,或验证重型初始化操作是否成功完成(例如,如果它们依赖于外部资源)。它也是一个注入依赖关系的好地方。
这基本上归结为干净地分离问题。构造函数的工作是创建对象的实例,初始化程序的工作是使复杂对象准备好用于预期用途,并且工厂的工作是协调这些工作并且仅返回即用型对象(相应地处理任何错误)。