7

我有以下问题:我有一组自动(监听事件)控制我的模型的引擎。下图显示了一般的类图: 类图

现在我有一个知道 EngineFacade 的客户端,我想从客户端的 Engine2 设置属性 Active,但是客户端和 EngineFacade 都不知道三个引擎中的哪一个是 Engine2。

有两种方法,但我不喜欢其中任何一种:

  1. 检查其中一个引擎是否属于 Engine2 类型 - 如果有另一个类执行相同的任务但名称不同,我必须在 EngineBuilder 和 EngineFacade 中更改它。
  2. 检查标识符字符串 - 我真的不喜欢魔术字符串。

我在客户端站点上所知道的是存在或应该有一个处理网格的引擎。但我不知道更多。

也许我必须在两个恶魔之间做出选择,但也许你们中的一个有更好的解决方案。

4

1 回答 1

1

您可以在 的实现上使用属性Engine2,如下所示:

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }

然后您将其应用于您的推导:

[HandlesGrid]
public Engine2 : EngineBase { ... }

然后,在您的客户端中,检查属性:

IEnumerable<EngineBase> bases = ...;

// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
    Where(b => b.GetType().
        GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());

// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;

这里的主要缺点(可能适用于您,也可能不适用于您)是您无法在运行时更改值(因为该属性是在编译时烘焙的)。如果您的引擎以这种方式不是动态的,那么属性是正确的方法。

如果您需要更改派生是否可以在运行时执行此操作,那么您必须退回到您的第二个选项,即识别引擎属性的代码结构。请注意,它不一定是字符串(我也不喜欢那样),但它可以是更有条理的东西,可以为您提供您正在寻找的信息。

于 2013-03-08T14:51:58.173 回答