Most efficient practice to access objects in other classes: Java - java

I am currently creating a dungeon crawler. I handle all of the dungeon generation, collision box generation, treasures and enemy generation, and player generation in one class called Dungeon. Each of the objects created in the dungeon class has a getter.
In the Main class, I am using an animation timer to handle all of the updates from the player moving, opening treasures, etc. This requires access to many of the objects created in the Dungeon class.
I am trying to better understand the use and benefit of object references in Java. My question is: What is the more efficient method to access the variables in the Dungeon class (or any other class for that matter) since I am accessing them hundreds or thousands of times?
For example, all of the treasures in the dungeon are in an ArrayList variable that is a member variable of the Dungeon class. So, I can retrieve that array list in my Main class like this: dungeon.getTreasureList(). If I need to get a specific item in that ArrayList I could use: dungeon.getTreasureList().get(i) where i is the index of the treasure object I want. This is fine for short calls (organizationally speaking) but it gets really messy with longer calls like so: dungeon.getPlayer().topIntersects(dungeon.getCollisions().getWalls())
Alternatively, I could create a reference to the treasureList in my Main like this: ArrayList<Treasure> treasure = dungeon.getTreasureList(). Then, if I need a specific object in the ArrayList I can call: treasure.get(i). This can clean up the long call above to something more like this: player.topIntersects(collisions.getWalls());. This is much easier to read and, as a result, I favor this method a bit more.
Disregarding the organizational benefits, is it a better practice to create a reference to access a variable to access information, or use the longer form and getters (like thisdungeon.getTreasureList().get(i))?
It would seem, that by creating a reference for player and collisions in the call dungeon.getPlayer().topIntersects(dungeon.getCollisions().getWalls()) I am saving two function calls by using player.topIntersects(collisions.getWalls());. Namely, one function call to dungeon.getPlayer()and one call to dungeon.getCollisions().
Since this is being called thousands of times while the game is running, it seems safe to assume I am saving many thousand function calls to dungeon.getPlayer()and dungeon.getCollisions(), resulting in a more efficient code. Am I right in this assumption?
EDIT: Trying to make the question more objective and less opinion based and corrected misleading phrasing

My opinion is that this question will be closed soon, because it's too opinion-based.
But if I did offer my opinion I'd say that letting classes access private collections and then operating with them is poor encapsulation.
Better to hide those details and provide methods to give the information you want without giving away the private details.

Related

Does this violate the Single Responsibility Principle?

I am trying to write code to make a simple game.
Assuming that there is a class called Level in which it manages the functionalities for the level.
For example, there are some methods like spawnHero() and spawnEnemies(), start(), finish() and etc in the class.
if I put a private String method called PrettyTimeFormat that converts the game duration time into a nicely arranged format and uses it in the finish() method, would this violate the SRP?
If so, should I make a class called TimeManager and put the PrettyTimeformat method in that class in order to avoid SRP?
It looks like you are missing a Game object. Game has Level, Hero, Enemies, and GameTime. Game can be start()-ed and finish()-ed.
When you architect the solution think about real objects. Objects exist in real life, are living things that do real things and don't create objects that end with -er.

Game programming: passing main class to every object

I know it's not efficient, but I don't really know why.
Most of the time, when you implement your game you got a main class which has a loop and updates every frame and creates certain objects.
My question is why it's not considered efficient to pass the main class to every object in its constructor?
In my case, I developed my game in Java for Android, using LibGDX.
Thank you!
It increases coupling (how much objects depend on each other) and therefore reduces re-usability and has the tenancy to produce 'spaghetti code'. I don't really understand what you mean by not being 'efficient', but this is why you shouldn't do it.
You should also consider why you need that main class in every single object. If you really think you do, you might need to reconsider your system design. Would you mind elaborating on why you think you need it?
Mostly, it is a matter of coupling the code and making proper design decisions.
You should avoid dependencies between classes whenever possible. It makes the code easily maintainable and the whole design clearer.
Consider the case: you are creating a simulation racing game. You have a few classes for such entities: wheel, engine, gearshift knob, etc... and non-entities: level, player...
Let's say, you have some main point (i.e. GameEngine class where you create instances).
According to you're approach you want to pass GameEngine's instance in entities constructors (or related mutator methods). It's not the best idea.
You really want to allow wheels or breaks to have the knowledge about the rest of the world (such as player's informations, scores, level etc.) and give them access to it's public interface methods?
All classes should have at small level of responsibility (and knowledge about other items) as possible.
If you really need reference to some kind of main point object in you're classes consider using dependency injection tools, such as Dagger.
It won't make you're game design better, but, at least, forces you to favor composition over inheritance - what leads to create better code.
It's not entirely inefficient, since (afiak in the general case) passing a reference to a method is quite cheap when you consider the number of JVM opcodes required, however, a possibly more efficient way of doing this would be to make a static instance of the game class and access that static field from the other classes. You would have to test these two options yourself.
In addition, passing a reference to the methods could make maintaining the code harder, as you have ultimately added a dependency.

HashMaps fast enough?

Im building my own little Opengl Library based on Lwjgl. In the moment im using HashMaps for storing things like render objects, scens or shader programs, because i want to have on Class the user can see, and there create methods to modify, create, i dont know... other objects or classes which are protected.
So, to explain this:
There is a class called "ShaderProgram". But instead to allow the user to create one, with ShaderProgram s = new ShaderProgram(...); , i create a method in my "main class", called "createShaderProgram", give it the params, create a shader program and put it to the hashMap called shaderPrograms, with a name the user decides. for example with MyClass.createShaderProgram("particle_shader", ...) i can create a shader for my particles, and then with MyClass.binShaderProgram("particle_shader") or something like this, i can use it.
BUT: Is this fast enough? Or are there other reasons to change it to int indicies, or, completely allow the user to use all the classes? Because for example im creating the render objects like this, too, and in each frame to do MyClass.getRenderObject("ACube").move(...) ... can i do this? What do you think about this?
Access complexity time for hash table is O(n) in the worst case:
Time Complexity of HashMap methods
So Yes, I would say that if performance accessing your objects collections is so important you should use 1:1 indexed collections like arrays.

Storing large variety of objects with different functionalities

I'm developing a game in Java which I can only describe as a variant of The Sims.
The main interface for the game consists of a level and will have a large variety of furniture which can be placed on the map. My problem is that whilst I can think of ways to construct a system which will allow me to assign properties to each item of furniture, I want to make sure I do it the correct way before I head down a long path to completing it. For example, if I referenced an object with an identifier of "sofa", the furniture object's members could be accessed through searching through all available objects and finding the one with the matching identifier.
My method would be to make a very large .java file with instances from a base furniture class for each item of furniture, with each one having an identifier and all its different properties assigned, such as image, position, rotation etc, plus their own unique code for each different function they provide (eg. sitting, sleeping).
For saving/storing these objects in a text file, I would just store the name of the identifier in the string array in the text file and when loading, I could just create the object by instantiating the object the identifier points to.
Would I be correct in using most of these methods, or are better ones available? If you've found it a struggle to comprehend what I've written (and I had trouble writing it clearly), then a more simple question would be:
How are items of furniture managed in The Sims with respect to the sheer amount available and the many different variations/rotations they can be placed in (and stored/saved)?
I think what you need to do here is try and abstract as much of the common functionality to the base classes and then each item should extend as necessary.
Eg
A Sofa... Seat extends Furniture extends Object
A Office chair would be the same
A DiningTable would be different tho... Table extends Furniture extends Object
You will also want various Interfaces so that a Sofa implements Sittable think of the functionailty that might be common to different objects, like they might all be Placeable
Also for saving and loading you might want to make your objects serializable.
Read up on Abstraction, Interfaces and Serialization
Component-Entity-System may be a good thing for you to look into. It's basically what you're describing. There's a large collection of entities, each entity has a collection of Components, and there are systems which know what to do with certain components.
EG: A piece of furniture is an entity named "chair". It has many components, one of them is "Renderable". And your game loop passes all renderables into the "renderer" System which calls the Renderable.render() method.
Note, this isn't very object oriented, but I find it's tough to design games like this in an OO way because the object hierarchies explode. Everything has some things in common with everything else. You'd end up with generic classes like "Unit" and "Thing" which isn't very OO either.

Private Class Variables vs Excessive Argument Passing

I am currently working on a single activity Android app that uses a lot of shared UI objects (like Button, etc). At the moment, I have these UI objects declared as private non-static class variables. The alternative to this would be to continually pass the objects from method to method and modify them that way. It is currently unclear to me which option should be preferred, as it seems to me that using the maximum encapsulation form would cause me to do quite a bit of argument passing. Can anyone shed some light on this?
Generally I like to think of encapsulation as hiding data within a single class. If multiple methods are accessing that object within the class, that doesn't really violate encapsulation principles. Once you start leaking it outside the class, that's when encapsulation problems occur.
With that said, it is perfectly fine to have a private member which is a Button and multiple methods can access that button.
As above Jeff said You should go for passing arguments as you are inside one activity as you have mentioned in your question and encapsulation is always the first thing to be recommended.I will suggest to do one more thing if you can :
Define one function which will accept the color code or color type, and call this function from all the functions where you want to change the button text color.In this way code can be in one place which is performing the same operation i.e. changing the color.
It depends if those private non-static variables that you want to pass as arguments actually make sense to become the properties of the class.If you think it makes sense and have design control over their updation/modification you can go ahead and declare them as class members

Categories