Saturday, May 6, 2017

Classes and Class Relationships: Part One

In order to discuss classes and class relationships, we are going to focus on creating a simple card game application. The application will allow players to play card games, such as Black Jack or Crazy Eights on the computer. There can be any number of players. In some instances, such as Black Jack, the computer itself will be a player--in this case the dealer. We will assume that the preliminary work of developing use cases for the requirements has been done. We will also be focusing on just the "domain" classes, the ones that describe the elements of the game play. We will not worry, for now, about the "Display" classes or any "Data Classes."

Defining the Objects


The first step is to figure out what the objects are. The best way to begin is to think about the program, in this case the game. Let's take Black Jack as an example. Describe it to yourself or to someone else. What are the nouns that show up. This program will do a card game. Cards are kept in a deck. There are players and each player will be dealt a hand of cards (in this case two cards). The player can choose to take an additional card on his or her turn. The player that gets closest to 21 without going over wins. (There are other rules, but we will let it be for now. )Just from this simple description we can come up with preliminary list:

  • Dealer
  • Card
  • Deck
  • Player
  • Hand
  • Turn

Let's look at card first. I am going to keep it very simple for this example. Each card object will have a suite and a card Number. The card number will be 1 to 13, because there are 13 cards in a suite. 1 is the ace and 13 is the king. The value of the card is not the same as the card number, it will be assigned by the particular set of game rules. Here is my first take on the card class.



The class has no methods. It is just storage for the card fields. I did not include the gets and sets in the diagram. They can be assumed for each field. In a final version of this program, I would also place a string with the path to the image of the card.

Cards are in a deck. Let's look at the deck class.



The Deck class has one field which is an ArrayList of cards. It also has three methods. The first one, populateDeck is private and would be called by the constructor. It puts the 52 cards usually found in the standard card deck into the ArrayList. Another method shuffles the deck, and the third returns the deck to a calling class.

Here are my first takes at the Hand and Player classes.



The Turn and Dealer classes I folded into particular game classes. They are both somewhat specific to particular game types. Instead at this stage I created some classes to show what typical game classes look like.



Remember this is all just a preliminary take.

Class Relations


The next step is to figure out the relationships between the classes are.

There are four kinds of relationships:

  • Association--A simple relationship in which one class calls a method in another class.
  • Inheritance--A relationship between a Parent class, a more general class, and a child or more particular class. User/Customer, for instance, or Vehicle/car.
  • Aggregation--a relationship in which one object is contained in another object, but independent of the containing object. If you destroy the container the object still exists.
  • Composition--A relationship in which the object is contained in another object and is dependent on the container. If the container is destroyed so is the contained object.

A Card is contained in a Deck. It can be argued if the deck is destroyed so are the cards. One could probably argue the opposite as well, but for now I will go with Composition as a relationship. The Player has an association with the game, Black Jack, for example. The player also contains a hand of cards. If the player goes so does the hand. At this point, I don't see any instances of inheritance or aggregation. Here is my preliminary Diagram with relationships.



Refractoring


There are still several problems with this diagram. The three game classes seem awkward. There should be a more efficient way to handle them. There is also a lot of repetition in their methods. Whenever you find repetition, you need to abstract it a higher level. In this class I made a Game class. The class has the stereotype "Abstract," which means the class can never be directly instantiated. Only its children can be. I put the methods from the game classes into an interface. An Interface consists only of method signatures. It behaves like a contract. Any class that implements the interface MUST have those methods and give them a body. Because Game is abstract, it doesn't have to implement the methods, but any child class will have to.

I made two other changes to the diagram. I abstracted the Suit field out of Card and made an Enumeration for it. It makes it easier to use and guarantees consistency. Finally I changed the relationship bewtween Card and Hand to Aggregation--though one could argue either way.



A couple things are unclear in the diagram. The relationship between Hand and Game is an Association. The relationship between Hand and Card is Aggregation. In the diagram the lines overlap.

Part two looks at the realization of this diagram in Java code.

No comments:

Post a Comment