我非常清楚类型检查,但发现自己处于一种独特的境地,我开始质疑我是否在最佳实践中。希望经验丰富的评论会给我一些方向和值得深入思考的事情。并且,说实话,并不是我所拥有的不会起作用,但是当我做出其他改变时,我想知道陷阱可能是什么以及我是否应该改变策略。在那里看起来并不多(实际上我没有看到任何基本类型检查占据了大部分搜索结果)。
我的情况是我正在开发物料清单接口系统。在此系统中,以下类图适用:
一般来说,这里的重点是,只有三种具体类型值得关注。因为在对象的构造函数中设置属性值很容易,所以我已经定义了(当然一般再说一遍)IMaterial接口:
public interface IMaterial
{
bool IsCommodity { get; }
bool IsAssembly { get; }
bool IsUnclassified { get; }
...
}
最初的想法是,对象图几乎没有改变的余地,通过预设的布尔值提高了性能,我不必担心通过类型检查具体类型来打破其他各种原则。 / p>
例如,我可以这样做......
bool hasCommodities = materialCollection.Any(item => item.IsCommodity);
bool hasAssemblies = materialCollection.Any(item => item.IsAssembly);
bool hasDescriptionOnly = materialCollection.Any(item => item.IsUnclassified);
或者这......
if (bomMaterial.IsAssembly)
{
symbol = new BomAssemblySymbol();
}
else
{
symbol = new BomItemSymbol();
}
而不是......
bool hasCommodities = materialCollection.Any(item => item is ClassifiedItem);
bool hasAssemblies = materialCollection.Any(item => item is Assembly);
bool hasDescriptionOnly = materialCollection.Any(item => item is UnclassifiedItem);
或者这......
if (bomMaterial is Assembly)
{
symbol = new BomAssemblySymbol();
}
else
{
symbol = new BomItemSymbol();
}
因此,就我而言,接口对属性的使用意味着对实现细节中具体类型的依赖性较小。但话又说回来,它引出了一个问题,如果出现另一种类型会怎么样?这里最好的答案是什么?是否有一种模式,我可能会忽视,应该考虑这个?如果有人想知道为什么消费代码会关心,那是因为在CAD系统中,用户与之交互的单个命令反过来利用这些对象。由于单行代码差异,我无法为它们创建单独的命令。 的更新 这是一个更完整的例子,展示了CAD方面如何瓶颈过程。 TryGetMaterialInformation()方法提示CAD系统中的用户输入特定输入。 SymbolUtility.InsertSymbol()方法只包含一组常用的用户提示,用于插入任何符号,然后插入它。
public override void Execute()
{
IMaterial bomMaterial = null;
bool multipleByReference = false;
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
if (!TryGetMaterialInformation(out bomMaterial, out multipleByReference))
{
ed.WriteMessage("\nExiting command.\n");
return;
}
IBlockSymbol symbol;
if (bomMaterial.IsAssembly)
{
symbol = new BomAssemblySymbol();
}
else
{
symbol = new BomItemSymbol();
}
if (multipleByReference)
{
SymbolUtility.InsertMultipleByReferenceSymbol(symbol, bomMaterial);
}
else
{
SymbolUtility.InsertSymbol(symbol, bomMaterial);
}
}
来自SymbolUtility
internal static void InsertSymbol(IBlockSymbol symbol, IMaterial material)
{
ICADDocumentDTO document = new CADDocumentDTO();
Editor ed = document.ActiveDocument.Editor;
//Get the insert point
Point3d insertPoint = Point3d.Origin;
if (!CommandUtility.TryGetPoint("Select insert point: ", out insertPoint))
{
ed.WriteMessage("\nExiting command.\n");
return;
}
//Insert the object
using (ISystemDocumentLock documentLock = document.Lock())
{
CreateSymbolDefinition(symbol, document);
symbol.Insert(insertPoint, material, document);
}
}
答案 0 :(得分:1)
如果您拥有IsClassified
,IMaterial
和IMaterial
等属性,则应描述某种可归因于实例的逻辑属性。他们应该不告诉消费者具体类型是什么。
原因是<form method="POST" data-request="Component_2::onSubmit" data-request-flash>
的消费者既不知道也不需要知道实现AJAX handler 'Component_2::onSubmit' was not found.
的任何具体类型。
如果这些属性实际上指示了具体类型,那么所有这些属性都是类型检查,它们将导致将对象转换回其具体类型,从而破坏了创建抽象的目的(界面。)
它看起来像我,因为你正在考虑将属性作为类型检查的直接替代方法。
替代方案是,消费者只是告诉类做什么(调用方法)而不是消费者查看类属性并决定对类做什么或不做什么,而类本身的实现决定了如何实现这一目标。