There is never one "right" or "wrong" way to do something in programming. Just ways which do or do not work for you, your team and your project. So don't worry about doing things the right way, worry about writing a program you can still understand, change and extend later. 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. 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: static CardType DOG = new CardType(image, a, b, ...); static CardType SHEEP = new CardType(image, a, b, ...); static CardType PIG = new CardType(image, a, b, ...); static int NUM_DOG_CARDS_PER_DECK = 3; static int NUM_PIG_CARDS_PER_DECK = 7; static int NUM_SHEEP_CARDS_PER_DECK = 7; [...] int i = 0; for (i = 0; i < NUM_DOG_CARDS_PER_DECK; i++) { deck.add(new Card(DOG)); } for (i = 0; i < NUM_PIG_CARDS_PER_DECK; i++) { deck.add(new Card(PIG)); } for (i = 0; i < NUM_SHEEP_CARDS_PER_DECK; i++) { deck.add(new Card(SHEEP)); } 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: 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.