У меня очень сложный типаж. Тип имеет несколько свойств только для чтения, и каждое свойство является сложным типом:
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 плачет. Я знаю, что это может быть решено намного лучше, чище и более SOLID, но я не видел решения.
Я пробовал использовать интерфейсы, но поскольку каждый построитель возвращает другой тип, он не имеет никакого дополнительного значения.
Другой подход, о котором я думал, - это новый FinalResult
и пусть каждый метод Build
принимает это как третий параметр: public ComplexTypeX Build(Dependency dep, OtherDependency otherDep, FinalResult finalResult)
. А потом вернуть пустоту. Теперь у всех построителей одинаковая сигнатура метода. Обратной стороной этого подхода является то, что вы испытываете искушение использовать свойства FinalResult
, которые еще не установлены.
Мне бы хотелось услышать, как решить эту проблему красивым объектно-ориентированным способом.