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

时间:2014-08-20 08:30:31

标签: java design-patterns

我正在尝试创建一个可以在不同平台上工作的简单游戏作为概念证明。现在我很高兴它能够同时适用于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(),这是平台实现所不期望的。
 *平台的实现必须抛弃所有接口,以便它们可以访问GameSprite中的真实数据。因此,如果在loadSrite 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);
    }
}

这样,游戏逻辑将无法调用新的Sprite(),因为它是泛型类型,也不能扩展它,这解决了第一个问题,我们不需要将其转换回来,因为泛型将提供正确的类型。问题是我必须在我的所有游戏逻辑类中添加泛型,并且每个接口都有一个通用参数,最后可能会有很多。

有没有更好的解决方案?我不知道的任何设计模式我可以用于此目的吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

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

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