Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 应该使用哪种设计模式来避免其他实现?_Java_Design Patterns - Fatal编程技术网

Java 应该使用哪种设计模式来避免其他实现?

Java 应该使用哪种设计模式来避免其他实现?,java,design-patterns,Java,Design Patterns,我试图创建一个简单的游戏,可以在不同的平台上工作,作为概念证明。现在,我很高兴它能同时适用于J2SE(使用AWT或Swing)和Android。我决定使用Java作为游戏的逻辑,因为这两个平台都需要Java代码。其想法是创建一组接口来抽象操作系统,并使用这些接口创建一个简洁的游戏逻辑。这些接口有两个实现,每个平台一个 一些代码来描述我的意思: public class MyGameLogic implements GameLogic { private GameSprite _sp

我试图创建一个简单的游戏,可以在不同的平台上工作,作为概念证明。现在,我很高兴它能同时适用于J2SE(使用AWT或Swing)和Android。我决定使用Java作为游戏的逻辑,因为这两个平台都需要Java代码。其想法是创建一组接口来抽象操作系统,并使用这些接口创建一个简洁的游戏逻辑。这些接口有两个实现,每个平台一个

一些代码来描述我的意思:

public class MyGameLogic implements GameLogic {  

    private GameSprite _sprite;

    @Override
    public void init(GamePlatform platform) {  
        _sprite = platform.loadSprite("arena");
    }

    @Override
    public void draw(GameCanvas canvas) {
        canvas.drawSprite(_sprite, 100, 200);
    }
}
在这里,GamePlatform、GameSprite和GameCanvas将是接口。根据平台功能和API的不同,这些接口将以不同的方式在不同的平台上实现。同样,GameLogic是一个由游戏逻辑而非平台实现的接口。该平台将使用GameLogic接口初始化逻辑,并在每次需要时重新绘制,但预计未来将添加更多方法

即使我认为这个选项很好,我在这个设计中看到了两个流程:
*游戏逻辑可以创建自己的GameSprite实现,并使用它调用drawSprite(),这是平台实现所不期望的。
*平台的实现必须回溯所有接口,以便能够访问GameSpire中的真实数据。因此,如果loadSprite for J2SE中返回的GameSprite实际上是一个实现GameSprite的J2SESprite类,那么在调用draw()时,我应该将GameSprite转换回J2SESprite

为了解决我在添加泛型时想到的问题,但这会使代码变得非常难看,下面是与泛型相同的代码

public class MyGameLogic<
        Sprite extends GameSprite,
        Platform extends GamePlatform,
        Canvas extends GameCanvas>
    implements GameLogic<Platform, Canvas> {  

    private Sprite _sprite;

    @Override
    public void init(Platform platform) {  
        _sprite = platform.loadSprite("arena");
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawSprite(_sprite, 100, 200);
    }
}
公共类MyGameLogic<
精灵扩展了游戏精灵,
平台扩展了游戏平台,
画布扩展GameCanvas>
实现游戏逻辑{
私人精灵(Sprite),;
@凌驾
公共void init(平台){
_精灵=平台。加载精灵(“竞技场”);
}
@凌驾
公共空白绘制(画布){
画布.drawSprite(_sprite,100200);
}
}
这样,游戏逻辑将无法调用new Sprite(),因为它是一个泛型类型,也不能扩展它,这解决了第一个问题,我们不需要将其抛出,因为泛型将提供适当的类型。问题是我必须在所有的游戏逻辑类中添加泛型,每个接口都有一个泛型参数,最后可能会有很多

有没有更好的解决办法?我不知道有什么设计模式可以用于此目的


谢谢

您有一个游戏可能有两个或多个用户界面(Swing、Android)。对于业务应用程序,通常将用户界面与业务逻辑分开。业务逻辑放在服务层中,服务层是仅由用户界面代码使用的内部API。服务层处理并提供表示程序内容的域对象。用户界面代码放置在单独的表示层中。它将用户输入转换为对服务层的调用,并将从服务层返回的域对象转换为用户界面更改


你可以使用类似的设计。您可能有不同的表示层实现(对于Swing和Android),但有相同的服务层。

为什么您要说您必须转换为具体的sprite实现?从GameSprite到J2SESprite。@bigdestroyer GameSprite的实现可能因平台而异。例如,它可以是一个包含像素数据字节数组的类,也可以是对先前加载到GPU内存中的资源的引用。游戏逻辑不应该知道游戏精灵的背后是什么,但是平台/画布需要知道它。因此,在操作sprite数据之前,需要对实际实现进行转换。J2SESprite是我给J2SE实现起的名字,但是这个名字本身并不重要。我理解。你可以做一个设计,让混凝土层知道如何绘制。控制反转。你应该找到一个不需要浇铸的设计。非常感谢你的回答。我想这正是我想要实现的。在本例中,GameSprite、GamePlatform和GameCanvas由表示层实现,MyGameLogic实际上是我的业务逻辑。但我所要求的是,任何设计模式都可以使这个体系结构保持干净的代码,以及如何避免业务逻辑可以为只有表示层应该提供的接口创建实现。有什么想法吗?