Win a copy of Java Mock Exams (software) this week in the Programmer Certification (OCPJP) forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

global array of objects that any class can access?

 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator


I have public array of players that I have declared to keep track of all the player information during the game. This array is  given spaces for 4 players  in the mainwindow class that extends game and then initialized  with a for loop once the number of players is selected. All classes that need to get the player information extend game or extend another class that extends game. My problem is though after the players are created when another class tries to access the variables they get null pointer exceptions. I believe this is because every time a new  class Game is created the gamePlayers array points to null right? So how do I have  a global array of player objects that any class can access?


[HENRY: Fixed Code format]
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:. . . So how do I have  a global array of player objects that any class can access?
Why do you want a global array? Global variables are error‑prone. Remember that arrays are always mutable; you can always say
MyArray[123] = something;
If you have nulls in your array, you can avoid that by creating the array via an array initialiser, or otherwise populating the array.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
making the array static solved my problem
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:making the array static solved my problem
I am 99% sure it didn't solve the problem. It probably added several new problems.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
what kind of problems could it have added? If you have 4 players in a game  with numerous classes that need to access information on the player class  in a turn based game depending on whose turn it is aka player object number how else would you do it other than a  global array of players?
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you make the array static, then you are only ever allowing for one game; if you start a second game, then you will have those players playing the first game.
You can easily make the array private to the game class; there are ways to make it available to other code which has business knowing the players via getXXX methods. You can even do it in such a way that the original array cannot be changed outside the game object. There are lots of ways to achieve what you want without global variables.
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Classes that need information from the Game do so by interacting with the instance of the Game through methods defined in Game. They have access to the Game because you pass the Game to those classes in their constructors or methods. Don't interact with a class' fields directly, and don't extend a class just to get access to its members.

Let's say that you have some sort of user interface that needs to display information from the game. It can access the information like this:
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
so even if I run two copies of the same program jar ( make a duplicate jar file using the os) file both will have the same player objects ? I wasn't intending on having more than one game being played at any point and time., or allowing anyone else to be able to that  as it doesn't make much sense., or ever needing to make different game object.
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:what kind of problems could it have added?

It's very easy to introduce bugs in these kinds of programs, because objects can't guarantee that their fields are in a valid state, because they can be accessed by anyone, from anywhere.
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:so even if I run two copies of the same program jar ( make a duplicate jar file using the os) file both will have the same player objects?

No. Different program executions will have separate state.

I wasn't intending on having more than one game being played at any point and time., or allowing anyone else to be able to that  as it doesn't make much sense., or ever needing to make different game object.

That doesn't matter. Even if you only ever have one instance of a type, it's very bad to make it available globally if it doesn't represent a constant value. It becomes incredibly easy to make mistakes that will cause bugs that are hard to track down.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Classes that need information from the Game do so by interacting with the instance of the Game through methods defined in Game. They have access to the Game because you pass the Game to those classes in their constructors or methods. Don't interact with a class' fields directly, and don't extend a class just to get access to its members.

Let's say that you have some sort of user interface that needs to display information from the game. It can access the information like this:




but they don't need any information from game just  the  player class. I know about making methods to access the information in  a class but java is objected oriented  and was made resemble real world interactions and in the real world if a bazar owner wants to talk to a  Army leader he doesn't need to talk to anyone  else.  It would be easy if I only  had one player to use the player class getters and setters  and / or other methods to modify the player class but there could be up to 4 of them who are playing in front of one computer.  So other classes that interact with player need to know which player they are interacting with and there need to be a away to store all 4 players information and access / modify it;  and  to make even more getters,  setters, and other methods in the game class that just call the player class  methods seems kind of redundant.
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This will be easier if you can give an example of a class that needs access to a single player. We can then show you a small example of how it's done, without having to use global data.
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:so even if I run two copies of the same program jar . . . file both will have the same player objects ? . . .
If you make the array static, yes. At least within the same JVM.
The bit about multiple copies of the same .jar is a red herring. If you run two copies of the same thing in two JVMs, what difference will there be if you start with the same .jar file or an identical copy?
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:This will be easier if you can give an example of a class that needs access to a single player. We can then show you a small example of how it's done, without having to use global data.



I know how to do it without global data it is just A LOT more work, and seems unnecessary but since this program is going to part a portfolio to help land me a job if making more methods to pass information will look better then make them I shall!. But also on side question what is a  red herring other than  a smoked fish that tastes like ham?
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65653
129
IntelliJ IDE Java jQuery Mac Mac OS X
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:. . . part a portfolio to help land me a job
If you want a job, don't let them see global variables.
. . . what is a  red herring . . .
Something which sends you on a wild goose chase.

Bear has already given you a more helpful link.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
is this a an acceptable  solution? or should I still write methods in the  Game class to call the over 200 public methods the player class has?

here is my main class




then in any class that needs to modify the player I write the other classes still extend game and other classes still extend them .



 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Also I just  made all fields of  game class other than numberofplayers private
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
my solution was not acceptable  still null pointers
 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:is this a an acceptable  solution? . . .. . .
No.

Don't make variables public. Unless you have a special arrangement with colleagues for special circumstances, make all variables private. Why are you giving things protected access in the second code block?

Your bits of code look as thought you were guessing what to do next. Don't. You can make 1000000 different guesses and there is a good chance a few will be correct, or you can plan the application beforehand and it will be right quickly. I think you shou‍ld turn your computer off and write down on paper what the game is supposed to be about.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know what the applacation is supposed  be about  now I'm redoing parts of  it  because my design stank. I extended every class to some other class.  I have written over 20,000 lines of code  I'm re doing some of it; if I had to rewrite it all I would just make something else instead.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Classes that need information from the Game do so by interacting with the instance of the Game through methods defined in Game. They have access to the Game because you pass the Game to those classes in their constructors or methods. Don't interact with a class' fields directly, and don't extend a class just to get access to its members.

Let's say that you have some sort of user interface that needs to display information from the game. It can access the information like this:



if  I do



how do I  access the same instance of game every time?





 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Game shouldn't have a JFrame. Game is part of your business logic, and a JFrame is part of the view.

Access the same instance of Game every time from where?
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have solved  my problem using the singleton design  method I think bay making a class that holds all of the information such as game map the array of  players  and making a static reference to that single class


 
Campbell Ritchie
Marshal
Posts: 53094
124
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Why on earth do you want a singleton?
That is not the correct way to implement a singleton even if you do want one. If you must, then do it like this:-
 
Junilu Lacar
Marshal
Posts: 10355
123
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote: I know what the applacation is supposed  be about  now I'm redoing parts of  it  because my design stank. I extended every class to some other class.  I have written over 20,000 lines of code  I'm re doing some of it; if I had to rewrite it all I would just make something else instead.

That's liable to scare employers away rather them attract them.
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, you replaced a globally accessible array with a globally accessibly mutable object. That's not really an improvement.

Every class needs the bare minimum of fields that they require to implement their behavior, without having to access static fields from elsewhere.

Let's take a simple game of Tic Tac Toe as an example. Here's how such a program could roughly look like:

You can see here that every class has exactly the fields they require in order to implement their methods. These fields are mostly set in the constructor.

An Application creates a JFrame and a GamePanel. When you click on a menu item for a new game, it shows a prompt to enter the players' names, and then it constructs a new Game which it sets on the GamePanel. Whenever the user clicks on one of the buttons of the GamePanel, the GamePanel instructs the Game to play a turn. The Game asks the current Player for a Move, and if the Move is valid, it places the current Mark on the Board in the corresponding location. Afterwards, GamePanel can update its entire user interface because it can access all the information it needs through the game field.
 
Junilu Lacar
Marshal
Posts: 10355
123
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Very nice example, Stephan!  I'd give a cow to see code like that more often around here.
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My game is a more advanced copy of the board game dark tower (https://boardgamegeek.com/boardgame/30/dark-tower). The player moves to various square and things happen to him. He could get into battle, get lost find food,  find gold, or buy / sell at the bazar or recrute men at town or castle  visit a tomb ruin or tower He has gold grain  water meat fruit oil, tents, canoes, wands armor , horses,  potions ect,  and array lists  for the various classes  of men he has in his army ( possibly should have only made one  soilder class and one array list but as it stands there are five ). The player is basically  a database with many functions to do things and interact with other classes.  There needs to be 1- 4 player objects modifiable by  most others classes with a place to store them,    I saw no other way to do this other than some kind of global something be it variable or class.



here are my player class fields



here are my player class functions some private some public



here are the classes that interact with player

LandSquare // the map tiles of land anything can occur from traps to finding things to battle
Bazar // a buy / sell shop
Tomb // a tomb where he can find stuff or battle with enemies can occur
Ruin // like a tomb again probably a redundant class
Tower // where the final battle happens for each of the five maps
RecurteMen // where the player can recrute new soliders of various kinds.
Battle // the fight class for player and enemies
ViewArmy // where can see his men
Inventory // shows what the player has
UpgradeMen // where after viewing his men he can upgrade them
Citidel // free food gold and men for  a weak player.
and of course the axemen bowmen, swordsmen knight, mage horse  and scout classes interact with it to.



 
Junilu Lacar
Marshal
Posts: 10355
123
Android Debian Eclipse IDE IntelliJ IDE Java Linux Mac Spring Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This group of methods and other method groups with similar name patterns are a code smell.

All those things after the "upgrade" could be classes of themselves. These could probably be boiled down to one polymorphic method:

where UpgradableCapability is an interface or abstract class. Interface might be the better choice here. The upgrade method can have a variatic parameter list:
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Even if you need all those separate classes to access the different players, you don't need the players to be globally accessible to do it. Either you invert control, or you pass the player to a method of the class that needs to operate on a player.

However, look at these classes: LandSquare, Bazar, Tomb, Ruin, Tower... They look like places a Player can visit. If that doesn't scream visitor pattern, than I don't know what does.

Next, your player seems to have a lot of properties that do the same thing. Why not make a class that can count the amount a player has of a certain property type?

A Battle class could then do something like this:
 
Jesse Matty
Ranch Hand
Posts: 34
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Even if you need all those separate classes to access the different players, you don't need the players to be globally accessible to do it. Either you invert control, or you pass the player to a method of the class that needs to operate on a player.

However, look at these classes: LandSquare, Bazar, Tomb, Ruin, Tower... They look like places a Player can visit. If that doesn't scream visitor pattern, than I don't know what does.

I got you on the visitable interface. But why another class to store player objects? and why to interfaces to go along with it? Also what does T mean?
 
Stephan van Hulst
Bartender
Posts: 6646
90
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jesse Matty wrote:I got you on the visitable interface. But why another class to store player objects?

If you mean player's properties, it's because it removes the need to add both a setter and a getter for each property. For instance, your Player has getFruit(), setFruit(), getGold() and setGold(). The getters do almost exactly the same, except they're for different properties, and the setters do exactly the same, except for different properties. Now, you can just declare en enum PropertyType which succinctly lists all the properties a Player can have, such as FRUIT, GOLD and HEALTH. Another advantage is that this approach allows other classes (such as your game display) to inspect the properties of your Player, without having to hard code all properties. Without the property class:

With the property class:

why to interfaces to go along with it?

Because you want encapsulation and separation of concerns. A class that only needs to display generic properties does not need to know how to edit the property, nor what the underlying data type of the property is. We can see that PlayerInfoPanel can work just fine with Property, knowing only how to get the type() and the value(). One of your game elements might have to edit the player though (such as when the player is in a battle), and needs a MutableProperty<SomeSpecificType> to update it.

Also what does T mean?

T is a generic type parameter. Property<T> essentially says: I am a property of some type that you can determine later. For instance, your Player can have a property of a completely different type than int:

Now, because we have these different interfaces, we can expose mutable properties to classes within the same package, and we can expose read-only properties to classes outside Player's package. This ensures that you don't accidentally corrupt your data from classes outside of your model.

A final advantage is that you can add listeners to your properties, so classes can get notified when they change.
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!