我试图在代码中模拟几个异构存储系统的容量利用率。
所有存储系统都有一些简单的概念,我试图从它们的具体实现中抽象出来。例如,所有系统都使用磁盘进行存储。可以将磁盘收集到一个组中,并将空间分配给这些组中的卷。某些系统具有特定的实现细节,这意味着它们的行为与其他系统不同。例如,几个系统具有不同类别的磁盘(例如快速,慢速),并且磁盘组属于一个类。有些系统只有一组没有相关磁盘类的磁盘。
我花了一些时间试图尽可能多地抽象出细节,并编写了一些接口来表示这些抽象。例如,IStorageContainer
具有名称,描述,一些标志以显示容器是否支持各种存储技术,以及原始总大小。我的愿望是IStorageContainer
可以代表一个磁盘,一组磁盘,一个磁盘类或一个卷。重要的是,IStorageContainer
有一个父IStorageContainer
和一些子IStorageContainer
来表示磁盘组如何分成卷,而卷必须属于一组磁盘。
我已经构建了代表每个存储系统的类,每个存储系统都实现了IStorageContainer
。我可以创建一个List<IStorageContainer>
,添加不同派生类型的对象组合,但所有派生类型都实现IStorageContainer
- 然后迭代列表以查找例如特定类型的对象。如果事先知道列表中对象的派生类型,我可以将它们从IStorageContainer
转换回原始类型:
foreach (var container in allContainers.SelectMany(
container => container.Children.Where(
child => child is System1Volume))
.Cast<System1Volume>())
{
// Do stuff with System1Volume
Console.WriteLine($"{container.Name}");
}
但是,如果我有一个List<IStorageContainer>
并且我事先不知道内容(即它们在运行时被“发现”),我想为每种类型显示不同的UI在列表中IStorageContainer
,我不知道如何发现底层类型。使用大量“if”语句执行此操作似乎很麻烦。
foreach
(var container in allContainers.SelectMany
(
container => container.Children
)
)
{
Console.WriteLine($"{container.Name} is a {container.GetType()}");
if (container.GetType() == typeof(System1Volume))
{
// Show the System1DiskGroup UI
var typedContainer = (System1Volume)container;
Console.WriteLine(typedContainer.WordThatOnlySystem1VolumesKnow);
}
else if (container.GetType()==typeof(System2Volume))
{
// Show the System2DiskGroup UI
var typedContainer = (System2Volume)container;
Console.WriteLine(typedContainer.WordThatOnlySystem2VolumesKnow);
}
}
有更好的方法吗?
最后,假设System1Volume
仅支持Children
列表中的一组特定派生类型。我可以使用从IStorageContainer
派生的接口作为约束来支持这个吗?