在重构我的应用程序并尝试添加一些抽象时,我发现了一个我自己无法解决的问题。
这是我真实问题的抽象,希望这更容易想象和理解。
有一个Container
课程,其中包含List<IContainerItem>
。
在我的应用程序中有两种类型的IContainerItem
:
ContainerItemA
ContainerItemB
IContainerItemFactory
还有一种方法:
IContainerItem Create();
对于这两种类型的IContainerItem
,还有IContainerItemFactory
实施:
ContainerItemAFactory
ContainerItemBFactory
现在,在通过IoC构建Container
时,会注入特定类型的IContainerItemFactory
,列表可以由特定工厂填充,一切正常。
问题已经开始,当我添加到我的应用程序IContainerItemPart
及其两个实现时:
ContainerItemAPart
ContainerItemBPart
现在要创建ContainerItem(A|B)
,您必须将构造函数ContainerItem(A|B)Part
传递给它。您无法传递IContainerItemPart
,因为IContainerIte
m的每个实现都使用特定IContainerItemPart
实现中的属性(不同的名称,不同数量的属性)
现在如何处理工厂? 界面中的Create方法现在看起来像:
IContainerItem Create(IContainerItemPart part);
我有两个选择:
IContainerItemPart
中的转换添加到工厂Create方法中的特定方法并将实现传递给构造函数IContainerItemPart
传递给IContainerItem
实现并投射到内部(在构造函数内)您认为哪种解决方案更好?也许没有一个?为什么? 也许问题出在我的架构上?那怎么解决呢?
更新
我提供一些代码来澄清。代码是有效的C#代码,工厂中的Create()方法除外。
interface IContainerItem { }
class ContainerItemA : IContainerItem
{
public ContainerItemA(ContainerItemAPart part)
{
Console.WriteLine(part.SpecificForA);
}
}
class ContainerItemB : IContainerItem
{
public ContainerItemB(ContainerItemBPart part)
{
Console.WriteLine(part.SpecificForB);
}
}
interface IContainerItemPart
{
int Id { get; }
}
class ContainerItemAPart : IContainerItemPart
{
public int Id { get; set; }
public int SpecificForA { get; set; }
}
class ContainerItemBPart : IContainerItemPart
{
public int Id { get; set; }
public int SpecificForB { get; set; }
}
interface IContainerItemFactory
{
IContainerItem Create(IContainerItemPart part);
}
class ContainerItemAFactory : IContainerItemFactory
{
public IContainerItem Create(IContainerItemPart part)
{
//dont work here, downcasting needed
return new ContainerItemA(part);
}
}
class ContainerItemBFactory : IContainerItemFactory
{
public IContainerItem Create(IContainerItemPart part)
{
//dont work here, downcasting needed
return new ContainerItemB(part);
}
}
class Container
{
private IList<IContainerItem> _items;
public Container(IList<IContainerItemPart> parts, IContainerItemFactory factory)
{
_items = new List<IContainerItem>();
foreach (var part in parts)
_items.Add(factory.Create(part));
}
}
答案 0 :(得分:0)
使IContainerItemPart
对象具有要使用的容器工厂。
interface IContainerItemPart{
IContainerItemFactory getItemFactory();
}
这样每个ItemPart将始终创建正确的itemFactory实现(并且可能将自身作为参数传递给itemFactory的构造函数)。
修改强> 现在使用代码示例:
以下是ContainerAFactory
的实现:
class ContainerItemAFactory : IContainerItemFactory
{
private IContainerItemAPart _part;
public ContainerItemAFactory ( IContainerItemPart part){
_part = part;
}
//now we don't have to pass the part subtype around as a parameter
public IContainerItem Create()
{
//look no downcasting needed
return new ContainerItemA(part);
}
}
现在IContainerItemPart
实施:
class ContainerItemAPart : IContainerItemPart
{
...
public IContainerItemFactory getItemFactory(){
return new ContainerItemAFactory (this );
}
}
因此,在您的代码中,您不需要知道它是A还是B项:
ContainerItem item = myItemPartFactory.getItemFactory().create();
答案 1 :(得分:0)
的问题
interface IContainerItemPart{
IContainerItemFactory getItemFactory();
}
是一个项目可能有一个带参数的构造函数。
我想知道一些观点。
期待回应。
此致,
Abdulmajid Alnouri