Skip to main content
edited body
Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

If you want to follow that architecture, you have two different classes Card and CardType. When there are 7 pig-cards in the game, you would have one CardType PIG and 7 instances of Card which alleach have a referencesreference to PIG which you can pass to it in its constructor. Your code to initialize your deck of cards could look something like this:

If you want to follow that architecture, you have two different classes Card and CardType. When there are 7 pig-cards in the game, you would have one CardType PIG and 7 instances of Card which all have a references to PIG which you can pass to it in its constructor. Your code to initialize your deck of cards could look something like this:

If you want to follow that architecture, you have two different classes Card and CardType. When there are 7 pig-cards in the game, you would have one CardType PIG and 7 instances of Card which each have a reference to PIG which you can pass to it in its constructor. Your code to initialize your deck of cards could look something like this:

added 4 characters in body
Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

But there is also a differentalways more than one way. Instead of having a CardType class, you could implement each card type as a separate class which inherits from Card. Then your code would look like this:

But there is also a different way. Instead of having a CardType class, you could implement each card type as a separate class which inherits from Card. Then your code would look like this:

But there is always more than one way. Instead of having a CardType class, you could implement each card type as a separate class which inherits from Card. Then your code would look like this:

added 191 characters in body
Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342

The pattern from the question has some implications for later maintainability. When each card is a static, they seem more like card-types to me than actual instances of cards. This conceptual difference might not matter much when each card only exists once in the game, but will matter when you allow multiple cards of the same type.

YouWith this pattern, you can write code like if (lastCard == Card.PIG) sayOink();. But because the ==-operator only checks if both references point to the same object, this only works when lastCard is a reference to Card.PIG. There might be multiple pig-cards in the game, but they are all represented by references to the one Card.PIG object. That means if Card.PIG has any internal state, that state will be shared by all pig-cards in the game.

When youyour game doesn't have state for individual cards, that's fine.

But if you have some mechanics where cards have a state (like counters on cards, a "tapping" mechanic like in some trading card games, etc...) or when you want cards themselves to be aware of their current location in the game (in the deck, in a player's hand, on the table), this is not going to work. You will then need somean instantiated object for each card.

for (int i = 0; i < NUM_DOG_CARDS_PER_DECK; i++) {
     deck.add(new DogCard());
}    
for (i = 0; i < NUM_PIG_CARDS_PER_DECK; i++) {
     deck.add(new PigCard());
}
for (i = 0; i < NUM_SHEEP_CARDS_PER_DECK; i++) {
     deck.add(new SheepCard());
}

The differences between different card types (like their names and images) would then be implemented in the various CardDogCard sub-classes, SheepCard etc.. This architecture would be most appropriate if your card types don't just differ by the values of their variables, but also have some mechanical differences which require card-specific code. That couldcode would then belong into those sub-classes.

The pattern from the question has some implications for later maintainability. When each card is a static, they seem more like card-types to me than actual instances of cards.

You can write code like if (lastCard == Card.PIG) sayOink();. But because the ==-operator only checks if both references point to the same object, this only works when lastCard is a reference to Card.PIG. There might be multiple pig-cards in the game, but they are all references to the one Card.PIG object. That means if Card.PIG has any internal state, that state will be shared by all pig-cards in the game.

When you game doesn't have state for individual cards, that's fine.

But if you have some mechanics where cards have a state (like counters on cards, a "tapping" mechanic like in some trading card games, etc...) or when you want cards themselves to be aware of their current location in the game (in the deck, in a player's hand, on the table), this is not going to work. You will then need some instantiated object.

for (int i = 0; i < NUM_DOG_CARDS_PER_DECK; i++) {
     deck.add(new DogCard());
}    
for (i = 0; i < NUM_PIG_CARDS_PER_DECK; i++) {
     deck.add(new PigCard());
}
for (i = 0; i < NUM_SHEEP_CARDS_PER_DECK; i++) {
     deck.add(new SheepCard());
}

The differences between different card types (like their names and images) would then be implemented in the various Card sub-classes. This architecture would be most appropriate if your card types don't just differ by the values of their variables, but also have some mechanical differences which require card-specific code. That could would then belong into those sub-classes.

The pattern from the question has some implications for later maintainability. When each card is a static, they seem more like card-types to me than actual instances of cards. This conceptual difference might not matter much when each card only exists once in the game, but will matter when you allow multiple cards of the same type.

With this pattern, you can write code like if (lastCard == Card.PIG) sayOink();. But because the ==-operator only checks if both references point to the same object, this only works when lastCard is a reference to Card.PIG. There might be multiple pig-cards in the game, but they are all represented by references to the one Card.PIG object. That means if Card.PIG has any internal state, that state will be shared by all pig-cards in the game.

When your game doesn't have state for individual cards, that's fine.

But if you have some mechanics where cards have a state (like counters on cards, a "tapping" mechanic like in some trading card games, etc...) or when you want cards themselves to be aware of their current location in the game (in the deck, in a player's hand, on the table), this is not going to work. You will then need an instantiated object for each card.

for (i = 0; i < NUM_DOG_CARDS_PER_DECK; i++) {
     deck.add(new DogCard());
}    
for (i = 0; i < NUM_PIG_CARDS_PER_DECK; i++) {
     deck.add(new PigCard());
}
for (i = 0; i < NUM_SHEEP_CARDS_PER_DECK; i++) {
     deck.add(new SheepCard());
}

The differences between different card types (like their names and images) would then be implemented in DogCard, SheepCard etc.. This architecture would be most appropriate if your card types don't just differ by the values of their variables, but also have some mechanical differences which require card-specific code. That code would then belong into those sub-classes.

Source Link
Philipp
  • 121.5k
  • 28
  • 261
  • 342
Loading