如何组织在各种类中重复的对象? Java

How to organize object repeated in various classes? Java

我正在 Java 开发一个基本的纸牌游戏,我已经准备了一组 Managers 子 class 子 class 子 class 子 class 子 like PlayerManager interacting with DeckManager ) 但是,要实现这一点,我需要在每个需要它的 class 中放置一个管理器。所以,例如:

if PlayerManager needs to a card from a deck --> executes drawCard() inside DeckManager,
so inside PlayerManager there's a DeckManager object.

问题是,如果这是正确的继续进行方式,我不会这样做,因为 每次 Manager 需要另一个,我都必须在其中创建所需的经理需要它

有没有更好的方法?我想做一个class包含所有的Managers,做成static,但是不知道好不好用在Java.

一个简单的解决方案是使用单例模式

在你的管理器中 class 有一个方法,returns 那个 class 的实例如果存在,如果不存在则对象被实例化。

public static synchronized Manager getInstance()
    {
        if (instance == null)
            instance = new Singleton();

        return instance;
    }

然后您可以调用属于 class 的对象的任何方法。

来源:http://www.oodesign.com/singleton-pattern.html

您应该研究单例模式来解决这个问题,然后每个管理器都有一个实例,可以 'injected' 进入需要访问它的任何其他管理器:

public class MyManager {

    private static MyManager singleton = new MyManager();

    /* Prevent instantiation
     */
    private MyManager() {
    }

    /* return single instance */
    public static MyManager getInstance() {
        return singleton;
    }
}

注入如下:

public class MyOtherManager {
    private MyManager = MyManager.instance();
}

这是面向服务设计中非常常见的模式(我假设您的经理是您的服务层级)。

不推荐单例。它们防止同一进程中出现 运行 的多个实例(这对您的用例可能不重要,但一般来说),并且它们使单元测试变得更难(您不能模拟 DeckManager例如,这意味着这两个 类 的测试是耦合的,不能独立测试)。

通常,您会在创建对象时将管理器传递给对象。例如,如果您有一个带有 DeckManagerGame 对象,它可以创建每个 PlayerManager 并将其自身(或 DeckManager)传递给该对象的构造函数。

听起来依赖注入可以解决您的问题。依赖注入是将对象的依赖项注入其中的做法(通常通过 setter 或构造函数)。依赖注入框架(例如 Spring)可以帮助您管理它。考虑以下几点(注释是为了 spring 自动装配的好处——查看互联网了解更多详情:))

@Component
public class DeckManager implements IDeckManager {
    public Card drawCard() {
        // Implementation here
    }
}

@Component
public class PlayerManager implements IPlayerManager {

    private IDeckManager deckManager;

    @Autowired
    public PlayerManager(IDeckManager deckManager) {
        this.deckManager = deckManager;
    }

    public void doSomething() {
        this.deckManager.drawCard();
    }
}

Spring 会为您创建一个 DeckManager,注意 PlayerManager 需要创建一个并通过构造函数注入它。

以这种方式编程比在 PlayerManager 中创建 DeckManager 实例更可取,因为它创建松散耦合的代码,更易于测试(还有其他好处)。

您可能想使用 Singleton 模式。如果必须,请务必这样做,但还有其他选择。

考虑创建一个新的 class 来为您进行交互。当您意识到这个对象有一个自然名称时,您就会知道您做对了。

我在这里创建了一个名为 Game 的新 class,它应该允许您在适当的地方进行交互。现在请注意,我们可以同时进行多个 Game

class Player {

}

class Deck {

    private void shuffle() {

    }

}

class PlayerManager {

    final Collection<Player> players;

    public PlayerManager(Collection<Player> players) {
        this.players = players;
    }

    private Collection<Player> getPlayers() {
        return players;
    }
}

class DeckManager {

    final Collection<Deck> decks;

    public DeckManager(Collection<Deck> decks) {
        this.decks = decks;
    }

    private void shuffle() {
        for ( Deck deck : decks ) {
            deck.shuffle();
        }
    }

    private void deal(Collection<Player> players) {

    }
}

class Game {

    final PlayerManager players;
    final DeckManager decks;

    public Game() {
        players = new PlayerManager(makePlayers());
        decks = new DeckManager(makeDecks());
    }

    private Collection makePlayers() {
        return null;
    }

    private Collection<Deck> makeDecks() {
        return null;
    }

    public void shuffleAndDeal() {
        // Shuff all decks.
        decks.shuffle();
        // Deal to players.
        decks.deal(players.getPlayers());
    }
}