我正在用Java开发一个基本的纸牌游戏,我已经准备了一组Managers
子类,它们之间相互作用(like PlayerManager interacting with DeckManager
)但是,要做到这一点,我会需要将Manager放在需要它的每个类中。所以,例如:
if PlayerManager needs to a card from a deck --> executes drawCard() inside DeckManager,
so inside PlayerManager there's a DeckManager object.
问题是我不知道如果它是正确的继续进行方式,因为每次Manager
需要另一个,我必须创建所需的经理需要它的人。
有更好的方法吗?我想过要做一个包含所有Managers
的课程并将其设为static
,但我不知道它是否与Java有关。
答案 0 :(得分:5)
不推荐单身人士。它们阻止多个实例在同一个进程中运行(这对于你的用例可能并不重要,但一般来说),并且它们使得单元测试变得更加困难(你无法模拟DeckManager
实例,这意味着这两个类的测试是耦合的,不能独立测试。
通常,您会在创建对象时将管理器传递给对象。例如,如果您有一个Game
对象DeckManager
,则可以创建每个PlayerManager
并将自身(或DeckManager
)传递给该对象的构造函数。
答案 1 :(得分:2)
听起来像依赖注入会解决你的问题。依赖注入是将对象的依赖关系注入其中的做法(通常通过setter或构造函数)。依赖注入框架(例如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的实例更可取,因为它创建了松散耦合的代码,更容易测试(以及其他好处)。
答案 2 :(得分:1)
你应该研究一下Singleton模式来解决这个问题,然后会有一个可以被注入的每个管理器的单个实例'进入需要访问它的任何其他经理:
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();
}
这是面向服务设计中非常常见的模式(我假设您的经理是您的服务层)。
答案 3 :(得分:1)
您可能想要使用Singleton
模式。如果必须,请务必这样做,但也有其他选择。
考虑创建一个为您进行交互的新类。当你意识到这个物体有一个自然名称时,你就会知道你做的是正确的事。
在这里,我创建了一个名为Game
的新类,它允许您在适当的位置进行交互。现在请注意,我们可以同时进行多个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());
}
}
答案 4 :(得分:0)
一个简单的解决方案是使用单例模式
在你的manager类中有一个方法,如果它存在,则返回该类的实例,如果没有实例化该对象。
public static synchronized Manager getInstance()
{
if (instance == null)
instance = new Singleton();
return instance;
}
然后,您可以调用该对象上属于该类的任何方法。