来自Java背景,我必须在C#中实现一些东西。该类是一个域对象,由多个其他域对象组成。我不想拥有一个包含10个字段的构造函数,所以我想到了使用构建器设计模式!以下是我提出的建议:
public class MyDomainObject
{
public DomainObject1 Obj1 { get; private set; }
public DomainObject2 Obj2 { get; private set; }
public DomainObject3 Obj3 { get; private set; }
...
public class DomainObjectBuilder
{
private MyDomainObject _domainObj = new MyDomainObject();
public DomainObjectBuilder(DomainObject1 obj1)
{
_domainObj.Obj1 = obj1;
}
public DomainObjectBuilder withDomainObject2(DomainObject2 obj2)
{
_domainObj.Obj2 = obj2;
return this;
}
.....
public MyDomainObject Build()
{
// Construct and Return the MyDomainObject
}
}
}
现在这个实现线程是否安全?当我以下列方式实例化我的域对象时:
var myDomainObject = new DomainObjectBuilder(obj1)
.withDomainObject2(obj2)
.withDomainObject3(obj3).build();
如果withDomainObject2
和withDomainObject3
之间的通话由不同的线程处理,会发生什么?
答案 0 :(得分:0)
你不需要一个构造函数机智太多的东西....你可能不会调用这些方法的东西,意味着它们中的一些是可选的,我看到的也是我的java,但在这里经过一些回归.NET框架,你可以做得更简单......像这样:
A a = new A(Required properties){
Name="x",
Family="Y",
OpetionalProperty3 = "z",
.......
};
如果您没有任何要求,可以删除括号(当您定义可选属性时)。
A a = new A{
Name="x",
Family="Y",
OpetionalProperty3 = "z",
.......
};
关于你的案例和线程handeling,检查变量的'volatile'语法 - 它确保每个线程调用的字段中的最后一个值
答案 1 :(得分:0)
我还没有遇到任何在多个线程上拆分构建器的代码。给出您的要求的简单答案很简单(不,它不是线程安全的)。
使用您的MyDomainObject
类考虑此示例:
private MyDomainObject _myObj;
void Main(string[] args)
{
DomainObject1 obj1 = new DomainObject1();
_myObj = new MyDomainObject(obj1);
Thread oThread1 = new Thread(ThreadProc1);
oThread1.Start();
Thread oThread2 = new Thread(ThreadProc2);
oThread2.Start();
MyDomainObject myObjFinal = _myObj.Build();
DomainObject2 obj2 = myObjFinal.Obj2; //No guarantee that Obj2 is set or initialized
DomainObject3 obj3 = myObjFinal.Obj3; //No guarantee that Obj3 is set or initialized
}
void ThreadProc1()
{
DomainObject2 obj2 = new DomainObject2();
MyDomainObject myObjModified = _myObj.withDomainObject2(obj2);
DomainObject3 objNew = _myObj.Obj3; //No guarantee that Obj3 is set or initialized
}
void ThreadProc2()
{
DomainObject3 obj3 = new DomainObject3();
MyDomainObject myObjModified = _myObj.withDomainObject3(obj3);
DomainObject2 objNew = _myObj.Obj2; //No guarantee that Obj2 is set or initialized
}
如您所见,无法保证在主线程中Build()
之后调用任何对象时进行初始化或设置。尝试访问在不同线程中初始化的对象时也是如此。