【发布时间】:2021-11-17 08:16:08
【问题描述】:
我正在编写一个 API 来将数据导入我们的软件。
正如您在下面看到的,我的模型层次结构分为不同类型的模型(A 和 B)。
每个模型:
-
嵌入另一个模型:“ImportModel”嵌入“Production”,其中嵌入“Parts”
Ex : ImportModelA => ProductionModelA => List of PartModelA -
具有与自身相关的特定属性和一些共同的属性
public class ImportModelA : ImportModelBase
{
public string ImportModelAProp { get; set; }
}
public class ImportModelB : ImportModelBase
{
public string ImportModelBProp { get; set; }
}
public abstract class ImportModelBase
{
public ProductionModelBase Production { get; set; }
}
public class ProductionModelA : ProductionModelBase
{
public int ProductionModelAProp { get; set; }
}
public class ProductionModelB : ProductionModelBase
{
public int ProductionModelBProp { get; set; }
}
public abstract class ProductionModelBase
{
public List<PartModelBase> Parts { get; set; }
}
public class PartModelA : PartModelBase
{
public int PartModelAProp { get; set; }
}
public class PartModelB : PartModelBase
{
public int PartModelBProp { get; set; }
}
public abstract class PartModelBase
{
public short CommonProp { get; set; }
}
这是我的问题:
在我的模型特定的服务方法中,我别无选择,只能向下转换“生产”和“零件”模型以访问它们的特定属性:
public class ImportModelAManagement
{
public void DoModelASpecificStuff(ImportModelA importModel)
{
// First downcast
var production = (ProductionModelA)importModel.Production;
// Uses productionModelA specific property
Console.WriteLine(production.ProductionModelAProp);
// Second downcast
var parts = production.Parts.ConvertAll(p => (PartModelA)p)
.ToList();
// Uses partModelA specific property
var firstPartModelAProp = parts[0].PartModelAProp;
Console.WriteLine(firstPartModelAProp);
}
}
此方法为“external”操作,不能直接添加到模型类中。
作为替代方案,我已经尝试使用泛型,如下所示:
public class ImportModelA : ImportModelBase<ProductionModelA, PartModelA>
{
public string ImportModelAProp { get; set; }
}
public class ImportModelB : ImportModelBase<ProductionModelB, PartModelB>
{
public string ImportModelBProp { get; set; }
}
public abstract class ImportModelBase<TProductionModel, TPartModel>
where TProductionModel : ProductionModelBase<TPartModel>
where TPartModel : PartModelBase
{
public TProductionModel Production { get; set; }
}
public class ProductionModelA : ProductionModelBase<PartModelA>
{
public int ProductionModelAProp { get; set; }
}
public class ProductionModelB : ProductionModelBase<PartModelB>
{
public int ProductionModelBProp { get; set; }
}
public abstract class ProductionModelBase<TPartModel>
where TPartModel : PartModelBase
{
public List<TPartModel> Parts { get; set; }
}
public class PartModelA : PartModelBase
{
public int PartModelAProp { get; set; }
}
public class PartModelB : PartModelBase
{
public int PartModelBProp { get; set; }
}
public abstract class PartModelBase
{
public short CommonProp { get; set; }
}
向下转换问题现已解决。
不幸的是,随着代码库的增长,这种设计将很快变得无法维护。
我知道我的设计不正确,所以:
- 如何避免在这些嵌套模型上向下转换或使用“convertAll”?
- “访问者”模式是否适合解决此问题?
编辑:
不确定,但可以通过简化初始层次结构来解决此问题:
public class ImportModelA : ImportModelBase
{
public string ImportModelAProp { get; set; }
public ProductionModelA Production { get; set; }
}
public class ImportModelB : ImportModelBase
{
public string ImportModelBProp { get; set; }
public ProductionModelB Production { get; set; }
}
public abstract class ImportModelBase
{
public string ImportModelBaseProp { get; set; }
}
public class ProductionModelA : ProductionModelBase
{
public int ProductionModelAProp { get; set; }
public PartModelA Parts { get; set; }
}
public class ProductionModelB : ProductionModelBase
{
public int ProductionModelBProp { get; set; }
public PartModelB Parts { get; set; }
}
public abstract class ProductionModelBase
{
public string ProductionModelBaseProp { get; set; }
}
public class PartModelA : PartModelBase
{
public int PartModelAProp { get; set; }
}
public class PartModelB : PartModelBase
{
public int PartModelBProp { get; set; }
}
public abstract class PartModelBase
{
public short CommonProp { get; set; }
}
谢谢
【问题讨论】:
-
你展示的代码当然是例子,但是为什么你的对象需要层次结构呢?看起来您的一棵大类层次结构树与您的程序结构的结构不匹配。向下转型可能是过度设计的数据结构的标志。保持更简单,是我的猜测。
-
这个代码确实是例如。在我看来,这种层次结构对我来说非常明显,因为每个模型在概念上都是父模型的一部分(例如:HeadModel 或 LegModel 确实是 BodyModel 的一部分)。这就是我以这种方式使用继承和嵌套模型的原因。你说的更简单具体是什么意思?简化继承,如我的“编辑”部分所示,但它仍然有意义吗?
标签: c# properties downcast