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

lys*_*cid 5 c# architecture xna decoupling

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

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

public class GameCell
{   
        public Color Color { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

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

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

Jim*_*hel 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
         }
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是为.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
Run Code Online (Sandbox Code Playgroud)

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

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

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