如何组织在各种类中重复的对象? 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 的对象的任何方法。
您应该研究单例模式来解决这个问题,然后每个管理器都有一个实例,可以 '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
例如,这意味着这两个 类 的测试是耦合的,不能独立测试)。
通常,您会在创建对象时将管理器传递给对象。例如,如果您有一个带有 DeckManager
的 Game
对象,它可以创建每个 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());
}
}
我正在 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 的对象的任何方法。
您应该研究单例模式来解决这个问题,然后每个管理器都有一个实例,可以 '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
例如,这意味着这两个 类 的测试是耦合的,不能独立测试)。
通常,您会在创建对象时将管理器传递给对象。例如,如果您有一个带有 DeckManager
的 Game
对象,它可以创建每个 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());
}
}