首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java:访问资源和Demeter定律

Java:访问资源和Demeter定律
EN

Stack Overflow用户
提问于 2015-06-09 02:20:17
回答 7查看 707关注 0票数 16

概述

在我的(Android) Java游戏中,我有一个名为resources的类。顾名思义,这个类保存游戏的资源。我的所有OpenGL对象(精灵)都是在这里创建的

它看起来像下面这样(显然,与真实项目中的版本相比,这是一个简化的版本):

public class Resources {

    Hero hero;
    Enemy enemy;
    MenuButtons mainMenuButtons;
    Background background;
    Scene mainMenu;

    public void createObjects(){

        hero = new Hero();
        enemy = new Enemy();
        mainMenuButtons = new MenuButtons();
        background = new Background();
        mainMenu = new Scene(this);

    }
}

因此,在我的mainMenu场景中,我需要访问我的对象,因此我们可能会看到如下所示:

public class mainMenu implements Scene {

    Resources resources;

    public mainMenu(Resources resources){

        this.resources = resources;

    }

    @Override
    public void render(){

        resources.background.draw();
        resources.hero.draw();
        resources.enemy.draw();
        mainMenuButtons.draw();           

    }

    @Override
    public void updateLogic(){

        resources.hero.move();
        resources.enemy.move();
        resources.mainMenubuttons.animate();
    }

}

现在,上述方法只是访问资源中的对象及其方法的一种方式。但这真的违反了德米特的定律吗?如果没有,为什么不呢?如果是这样,那么以不违反LOD的方式访问这些对象的最佳方式是什么?

访问器-

一种选择(我已经排除了TBH -见下文)是将访问器方法放入我的资源类中。这样我就可以做一些类似的事情:

resources.drawBackround();

我有很多对象,每个对象的每个方法/变量都需要一个访问器。这并不实用,我似乎在编写大量的额外代码,最重要的是,它使得资源的类变得非常长,因为它充满了这些访问器。因此,我不会走这条路。

将对象传入场景的构造函数的

当然,我也可以这样做:

    hero = new Hero();
    enemy = new Enemy();
    mainMenuButtons = new MenuButtons();
    background = new Background();
    mainMenu = new Scene(hero, enemy, mainMenuButtons, background);

所以我可以简单地这样做:

    background.draw(); //etc....

这对于简单的场景是可行的(比如不需要很多对象的菜单系统),但是对于主游戏,它可能很快就会变得一团糟,因为我必须将对一些30+对象的引用传递到构造函数中,这听起来并不是很正确……

因此,如果有人能指出最好的继续进行的方式和原因,我将非常感激。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2015-06-17 00:01:26

,所以如果有人能指出最好的方法和原因,我将非常感激。

在我看来,最好的方法是保持Resources类,使所有对象都是私有的,这样就不会违反法律并编写访问器(但不是像您已经排除的那样为每个对象编写访问器)。

我有很多对象,每个对象的每个方法/变量都需要一个访问器。这并不实用,看起来我在写一大堆额外的代码,最重要的是,只要资源类中充满了这些访问器,它就会让资源类变得离谱。因此,我不会走这条路。

我假设许多对象都属于同一类。因此,您不必为每个对象都创建一个访问器,这将真正炸毁类。在一个游戏中,你通常有一个英雄,一个或多个敌人和许多精灵.

public class Resources {

    private Hero hero;
    private Enemy enemy;
    private MenuButtons mainMenuButtons;
    private Background background;
    private Scene mainMenu;

    public void createObjects(){

        hero = new Hero();
        enemy = new Enemy();
        mainMenuButtons = new MenuButtons();
        background = new Background();
        mainMenu = new Scene(this);

    }

    public Hero getBackground() {

        return background;
    }

    public Hero getHero() {

        return hero;
    }

    public List<Enemy> getEnemies() {

        ArrayList<Enemy> list = new ArrayList<Enemy>();
        list.add(enemy);
        list.add(next_enemy);
        return list;
    }

    public List<Sprite> getSprites() {

        ArrayList<Sprite> list = new ArrayList<Sprite>();
        list.addAll(enemy.getActiveSprites());
        return list;
    }

}

如果英雄和敌人是从同一个类派生的,那么除了getHero()和getEnemy()之外,还可以创建一个getActor()方法。getSprites()方法只是一个示例。

如果这个解决方案对你不起作用,我有另一个建议。

让Resources类做一些工作。

public class ResourceManager {

    private Hero hero;
    private Enemy enemy;
    private MenuButtons mainMenuButtons;
    private Background background;
    private Scene mainMenu;

    public void createObjects(){

        hero = new Hero();
        enemy = new Enemy();
        mainMenuButtons = new MenuButtons();
        background = new Background();
        mainMenu = new Scene(this);

    }

    public void render(Scene scene) {

        this.background.draw();
        if (scene != mainMenu) {

            this.hero.draw();
            this.enemy.draw();
        }
        this.mainMenuButtons.draw();           

    }

    public void updateLogic(Scene scene){

        this.hero.move();
        this.enemy.move();
        this.mainMenubuttons.animate();
    }

}

然后,mainMenu直接在RescourceManager类中调用逻辑方法。

public class mainMenu implements Scene {

    ResourceManager resourceManager;

    public mainMenu(ResourceManager resourceManager){

        this.resourceManager = resourceManager;
    }

    @Override
    public void render(){

        resourceManager.render(this);
    }

    @Override
    public void updateLogic(){

        resourceManager.updateLogic(this);
    }

}

我希望我的建议能帮助你弄清楚如何继续你的项目。

票数 4
EN

Stack Overflow用户

发布于 2015-06-13 01:55:09

你可以使用依赖注入并消除你的Resources类。然后你可以在你的字段上调用函数,而不会违反德米特定律。

下面是一个使用构造函数注入的示例:

public class MainMenu implements Scene {

   Background background;
   Hero hero;  
   Enemy enemy; 
   MenuButtons buttons

    public mainMenu(Background background, Hero hero,  Enemy enemy, MenuButtons buttons){

       this.background = background;
       this.hero = hero;
       this.enemy = enemy;
       this.buttons = buttons;   
    }

    @Override
    public void render(){

        this.background.draw();
        this.hero.draw();
        this.enemy.draw();
        this.mainMenuButtons.draw();           

    }

    @Override
    public void updateLogic(){

        this.hero.move();
        this.enemy.move();
        this.mainMenubuttons.animate();
    }

}

使用依赖注入,您可以将实例传递到构造函数和函数中,而不是在类中“更新”它们。不过,你需要在某个地方管理你的实例,有很多库可以帮你做到这一点。Dagger在安卓系统上很受欢迎:http://square.github.io/dagger/

票数 1
EN

Stack Overflow用户

发布于 2015-06-17 10:11:12

传递列表的想法是不错的第一步,但这还不够。游戏开发人员有一个(有点争议的)结构概念,叫做“场景图”,它可以帮助他们跟踪他们的资源(以及其他东西)。https://en.wikipedia.org/?title=Scene_graph

这是一个相当复杂的概念,但你迟早需要学习它。在gamedev.stackexchange.com上有很多好的建议,所以我建议你去那里偷看一下。

这里有一个关于这个主题的很好的YouTube视频教程。https://www.youtube.com/watch?v=ktz9AlMSEoA

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30716327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档