C# 将两个接口合并为一个
正如我在前面的问题中提到的,我正在重构一个我正在进行的项目。现在,一切都取决于其他一切。所有东西都被划分到我早期创建的名称空间中,但我认为我的划分方法不是很好。我试图消除一个对象依赖于另一个对象的情况,该对象依赖于另一个对象的不同命名空间中的另一个对象 我这样做的方式是将我的项目(游戏)划分为几个程序集:C# 将两个接口合并为一个,c#,.net,oop,C#,.net,Oop,正如我在前面的问题中提到的,我正在重构一个我正在进行的项目。现在,一切都取决于其他一切。所有东西都被划分到我早期创建的名称空间中,但我认为我的划分方法不是很好。我试图消除一个对象依赖于另一个对象的情况,该对象依赖于另一个对象的不同命名空间中的另一个对象 我这样做的方式是将我的项目(游戏)划分为几个程序集: GameName.Engine GameName.Rules GameName.Content GameName.Gui GameName.Engine程序集包含一组接口,因此程序的其他部分
GameName.Engine
GameName.Rules
GameName.Content
GameName.Gui
GameName.Engine
程序集包含一组接口,因此程序的其他部分不需要依赖于任何特定的实现。例如,我有一个GameName.Engine.ICarryable
接口,主要由GameName.Content.Item
类(及其子类)实现。我还有一个对象,允许参与者
拾取ICarryable
:拾取动作
以前,它需要一个项目,但这暴露了不必要的方法和属性,实际上它只需要拾取和携带它所需的方法。这就是为什么我创建了ICarryable
接口
好了,我的问题是GameName.Gui
应该只依赖于GameName.Engine
,而不是任何实现。在GameName.Gui
中,我有一个MapView
对象,它显示一个Map
和任何IRenderable
对象
IRenderable
基本上只是一个显示图像和一些描述对象的字符串的界面。但是,MapView还需要对象来实现iLocatable
,这样它就可以通过iLocatable
内的事件LocationChanged
,查看其位置并知道何时更改
这两个接口由Item
和Actor
对象实现。它们同样在GameName.Content
中定义。由于它需要两个接口,我有两个选择:
使GameName.Gui
依赖于GameName.Content
并需要实体
(项
和参与者的基类
)
在GameName.Engine
中创建一个如下所示的界面:
interface ILocateableRenderable : ILocateable, IRenderable
{
}
然后让我的Actor
和Item
对象实现该接口,而不是单独实现这两个接口
有人对哪种方法最好有什么建议吗?创建一个没有方法或属性、只强制实现另外两个接口的接口是否合适
澄清:MapView
处理由实体
对象组成的地图
。我不想将<代码>实体< /Cord>对象暴露到MavVIEW/COD>中,只需要知道它们的位置(<代码>不可引用的< /代码>)以及如何渲染它们(<代码>不可编辑< /代码>)。 你可以考虑的,但是我猜我在这方面不是专家,而是把引擎分成两个,一个渲染器和一个位置管理器。然后,可以将iLocatable对象添加到后者,将IRenderable对象添加到前者。然而,如果您认为这没有任何意义和/或过于复杂,那么创建这个合并接口似乎并不太糟糕。另一个选项可能是添加一个超级接口到ILCATABLE和RealDeable,例如IGAMObjor,您将在您的引擎类中接受,然后检查确切的类型以将对象发送到地图、位置或两者。 您可以考虑什么,但我想我在这方面不是专家,是将引擎分成两个,渲染器和位置管理器。然后,可以将iLocatable对象添加到后者,将IRenderable对象添加到前者。然而,如果您认为这没有任何意义和/或过于复杂,那么创建这个合并接口似乎并不太糟糕。另一种选择可能是向iLocatable和IRenderable添加超级接口,例如IGameObject,您可以在引擎类中接受它,然后检查将对象分派到地图的确切类型、位置对象或两者。
您似乎有两个相互冲突的要求:
内部GameName.Gui I
有一个地图视图对象,显示一个
映射和其上的任何IRenderable对象
及
但是,地图视图也需要对象
要实现iLocable,它可以
查看它的位置并知道它的时间
通过事件更改,位置更改,
在里面我是可以说话的
因此,如果MapView只需要IRenderable,那么它应该接受IRenderable,然后检查类是否也实现了iLocatable。在这种情况下,使用它的方法
public void Whatever(IRenderable renderable)
{
if (renderable is ILocateable)
{
((ILocateable) renderable).LocationChanged += myEventHandler;
}
// Do normal stuff
}
另一方面,如果您总是需要它是iLocatable和IRenderable的,那么您应该通过以下两种方式之一创建派生接口
或者
或
取决于您的代码目前的状态。您似乎有两个相互冲突的需求:
内部GameName.Gui I
有一个地图视图对象,显示一个
映射和其上的任何IRenderable对象
及
但是,地图视图也需要对象
要实现iLocable,它可以
查看它的位置并知道它的时间
通过事件更改,位置更改,
在里面我是可以说话的
因此,如果MapView只需要IRenderable,那么它应该接受IRenderable,然后检查类是否也实现了iLocatable。在这种情况下,使用它的方法
public void Whatever(IRenderable renderable)
{
if (renderable is ILocateable)
{
((ILocateable) renderable).LocationChanged += myEventHandler;
}
// Do normal stuff
}
另一方面,如果您总是需要它是iLocatable和IRenderable的,那么您应该通过以下两种方式之一创建派生接口
或者
或
取决于您的代码目前的状态。选项2违反了。基本上,客户端不应该看到它不需要的方法。。。没有胖接口。如果一个对象不能只实现这些接口中的任何一个,那么您应该将它们结合起来
interface IRenderable: ILocateable
{
// IRenderable interface
}
public void Whatever(IRenderable renderable)
{
renderable.LocationChanged += myEventHandler;
// Do normal stuff
}
public interface IRenderable : ILocateable
{
// IRenderable interface
}