如何从框架中正确地分离类(源级解耦)

时间:2011-12-02 20:02:14

标签: c# architecture xna decoupling

我正在使用Microsoft XNA框架开发一个游戏项目,尽管这个问题是涉及类/系统解耦的通用问题。

假设我有一个类(简化为适合此示例),如下所示:

public class GameCell
{   
        public Color Color { get; set; }
}

我想在使用C#的多个平台之间重用尽可能多的代码。

直接引用 Color 结构的问题是此类型是在XNA程序集中定义的,在我的代码和XNA之间创建了强耦合(或依赖)。

我将使用的另一个框架可能(或可能不)拥有自己的 Color 对象,具有自己的一组属性和API。

我希望有相同的源文件“知道”自动使用XNA或其他框架的实现。

我知道其他类型的解耦方法,比如IoC,但这意味着我会插入不同版本的系统/类,而不是在不同的上下文中重用相同的类。

这甚至可以吗?您如何建议保持这样的系统便携?

我已经看到了一些情况(在本机C ++开发中),您将定义一组类,这些类镜像您正在使用的框架所具有的类(例如,此处 - 再次定义Color),因此可以稍后“重新映射”以根据需要使用不同的类。

另一种选择是使用#IFDEF来使用类头中的using语句(从XNA切换到其他平台)。 在这种情况下,最好的选择是什么?

1 个答案:

答案 0 :(得分:5)

通常,您要创建自己的Color结构,并使用条件编译开关进行转换。例如:

#define USE_DOTNET
//#define USE_SOMETHINGELSE

#if USE_DOTNET
using System.Drawing;
#endif

#if USE_SOMETHINGELSE
using SomethingElse.Drawing;
#endif

public struct MyColor
{
    #if USE_DOTNET
    Color TheColor;
    #endif
    #if USE_SOMETHINGELSE
    SomethingsColor TheColor;
    #endif

    public int R
    {
        get
        {
            #if USE_DOTNET
                // code to return .NET Color.R value
            #endif
            #if USE_SOMETHINGELSE
                // code to return SomethingColor.R value
            #endif
         }
    }
}

另一种方法是为.NET和SomethingElse代码分别设置区域。例如:

#if USE_DOTNET
public int R
{
    get { return TheColor.R; }
}
// other properties and methods here
#endif

#if USE_SOMETHINGELSE
// properties and methods for using SomethingElse
#endif

这可以很好地工作,但是在编写代码时必须非常小心,这样就不会在这些可移植层中的任何地方使用.NET Color结构。

我们在开发必须在Windows,Mac和几种不同游戏控制台上运行的游戏时,在C / C ++中使用了这种技术。设置可移植层是一件痛苦的事情,但一旦设置好,它就会很容易使用。

但是,我要提醒您,不要让您的可移植性类和结构与.NET库或您正在使用的其他库中的类或结构具有相同的名称。如果你这样做,你会让自己感到困惑,并且你可能会编写一些你不会发现的非可移植代码,直到你开始尝试移植它。 (不是说我是根据经验或任何事情发言......)