【发布时间】:2020-05-07 08:53:48
【问题描述】:
我有一个非常复杂的类型。该类型有多个只读属性,每个属性都是一个复杂类型:
public class FinalResult
{
public ComplexType1 ComplexType1 {get;set;}
public ComplexType2 ComplexType2 {get;set;}
public ComplexType3 ComplexType3 {get;set;}
public ComplexType4 ComplexType4 {get;set;}
}
因为ComplextTypeX 很复杂,我为每个人创建了一个构建器:
public class ComplexType1Builder
{
public ComplexType1 Build(Dependency dep, OtherDependency otherDep)
{
// build / create the complex object
return complexType1;
}
}
public class ComplexType2Builder
{
public ComplexType2 Build(Dependency dep, OtherDependency otherDep)
{
// build / create the complex object
return complexType2;
}
}
// same for ComplexType3 and ComplexType4
最后我有 FinalResultDirector 将所有东西联系在一起:
public class FinalResultDirector
{
private readonly ComplexType1Builder _builder1;
private readonly ComplexType2Builder _builder2;
private readonly ComplexType3Builder _builder3;
private readonly ComplexType4Builder _builder4;
public FinalResultDirector(
ComplexType1Builder builder1,
ComplexType2Builder builder2,
ComplexType3Builder builder3,
ComplexType4Builder builder4 )
{
_builder1 = builder1;
_builder2 - builder2;
_builder3 = builder3;
_builder4 = builder4;
}
public FinalResult Build(Dependency dep, OtherDependency otherDep)
{
return new FinalResult
{
ComplexType1 => _builder1.Build(dep, otherDep),
ComplexType2 => _builder2.Build(dep, otherDep),
ComplexType3 => _builder3.Build(dep, otherDep),
ComplexType4 => _builder4.Build(dep, otherDep),
};
}
}
这行得通,但我的 OO 心在哭泣。我知道这可以解决得更好、更干净、更可靠,但我还没有看到解决方案。
我尝试过使用接口,但由于每个构建器返回不同的类型,它没有任何附加值。
我一直在考虑的另一种方法是新建一个FinalResult 对象,并让每个Build 方法接受它作为第三个参数:public ComplexTypeX Build(Dependency dep, OtherDependency otherDep, FinalResult finalResult)。然后返回无效。现在所有构建器都具有相同的方法签名。这种方法的缺点是您很想使用 FinalResult 上尚未设置的属性。
我很想听听如何以一种不错的 OO 方式解决这个问题。
【问题讨论】:
-
你为什么需要这么复杂的
FinalResult类,里面有复杂的类型?有没有想过解耦?它是否始终具有所有复杂类型,还是取决于某些逻辑?否则你可以看看fluent builder -
FinalResult不会编译,因为属性必须有名称,而不仅仅是类型 -
修复了代码。是的,据我目前所见,我需要所有这些复杂类型。
-
好吧,你已经将 4 个不同类型的构建器传递给了 director 类,但是将它们分配给了 4 个相同类型的变量
ComplexType1Builder。那你为什么需要4个建造者呢?此行将无法编译_builder2 - builder2;您是否尝试过至少构建您的示例?它不可能是真正的代码,因为它永远不会运行 -
如果您的代码可以工作但可能会更好(可能不是此代码)Code Review 是更好的匹配。不过,在发布之前请确保您有实际的工作代码。
标签: c# design-patterns solid-principles builder-pattern