I see this piece of code in almost every game example for Java. Create an instance of the Game class then execute the loop from that instance.
public static void main(String[] args) {
Game g = new Game();
g.gameLoop();
}
public Game () {
}
However, as I don't do anything apart from the execution of the gameLoop() why not write it like this? I don't really need to store the instance of Game anywhere do I? Like this.
public static void main(String[] args) {
new Game ();
}
public Game () {
gameLoop();
}
If so for what?
Both cases are working and have been tested by me.
if you write it like this:
new Game ();
This is done by using a constructor. A constructor's main purpose is to create objects and initialize any variables and set any initial value you need to set.
If you only write new Game(), it can compile, but doesn't mean it is a good way to implement. Why is it not a good implementation?
It is because doing so, you are as good as writing your entire game within the constructor. It is wrong to begin with, because you are actually not supposed to implement your entire logic in the constructor.
So why people do it as such:
Game g = new Game();
g.gameLoop();
Now, note the difference of this and the one you suggested (using a constructor). Doing so you modularize your codes into sub-problems. Benefit of modularization? Lots of it:
Easier to manage your codes
Easier to debug your codes, shorter debugging time
Write once, use it n times
Easier to read and maintain your codes
However, there are different ways you code with Java. It is also possible to make your gameLoop() static. So that you can do this (without instantiating an object):
Game.gameLoop();
This is possible, but I don't advise you doing this.
One reason is because of philosophy: constructors are for constructing things, not running them. But there is a practical concern as well. If you call gameLoop() inside of the constructor, then you have no way of creating a Game without running it. This could pose a problem if, say, you wanted to construct a game, then make some changes to its configuration, then run it. This scenario would make even more sense if you ended up subclassing Game.
Related
I am a newbie in java and I am working on a small university project, I have about 30 classes.
My project is to develop a game about constructing a city, and my expected game should include following features:
different kinds of construction(roads, building, and rooms) and inside objects (exit);
interaction between players and game objects, for instance, players can enter/leave the room.
I am just trying to avoid getting my main class so big with different objects, for example my game will be about 20 buildings and each building has different number of rooms and exits..
For reaching the design, I need to solve following questions:
Do I have to write all these objects inside the main?
Can I build it in another class for starting the game with players in the main?
I'm interpreting your question as being how to split up responsibilities to avoid classes becoming too cluttered and complex. That's a very good question but unfortunately there's no simple answer: there are many techniques and the ones that will work best in your case will depend a lot on your problems space.
You may have heard of the Single Responsibility Principle. Essentially this means that each class has responsibility for a single piece of functionality. Taking to its logical extreme this will mean your code will have many small classes that just do one simple thing. The only reason to change a class is if that one thing changes. So, for example, your main method might be responsible for staring the UI, but not setting up all the game data.
So how do you achieve this? There are several techniques for splitting logic out from a class to avoid it becoming long and cluttered but the most important (IMO) is Delegation. This involves delegating a piece of functionality to another class and then calling methods in that class.
For example:
class Game {
public static void main(String[] args) {
Game game = new Game();
game.setUpUI();
game.configureGameData();
game.start();
}
public void setUpUI() {
}
public void configureGameData() {
}
public void start() {
}
}
Might become:
class Game {
private final UI_Maker uiMaker;
private final GameData gameData;
private final GameStarter gameStarter;
public static void main(String[] args) {
Game game = new Game();
game.start();
}
private void start() {
uiMaker.makeUI();
gameData.loadData();
gameStarter.start();
}
}
This structure has a lot of advantages:
its generally more obvious to the reader what the class does
the delegates should be individually testable
you can change the implementation of the delegate without impacting the user
you can reuse delegated functionality elsewhere
refactoring structures is more straightforward
You can create the classes in the same package as the main(separate java files for the main, buildings, players, etc.) and as long as each class is public or protected(protected allows objects or variables to be accessed anywhere inside the package you are currently executing in), you will be able to create those objects in the main as you please.
As for creating the game, you will want to call the classes to generate the map in the main first then buildings, players and whatever else you need. Then call the methods on the objects that you need to run however your game is supposed to work.
I'm a beginner in Java programming and I'm currently working on an app with more complex class structure and a GUI. This might be a stupid questions, but it is very hard to google, so I'm asking here.
I have a main class, looking like this:
package app;
public class App {
private FirstClass fc;
private SecondClass sc;
public App () {
fc = new FirstClass ();
sc = new SecondClass ();
// ... code continues ...
}
}
Say the SecondClass is defined outside of this .java file (like GUI forms are). Is there a way for me to access the "fc" instance (or other member variables of the App instance) from the "sc" instance (without passing the "this" pointer)? Something like:
class SecondClass {
public void someMethod() {
getWhoeverCreatedThisInstance().fc.getSomeData();
// ... code continues ...
}
}
And if not, what am I doing wrong? Should I design this differently? Maybe setting the "fc" as static? But what if I want more of my app's classes to communicate with each other, should I make them all static? What would be the point of having something non-static then? I could pass the "this" pointer of "App" or "fc" instance in the constructor of "SecondClass", but that solution just seems non-elegant when the number of classes that need this behavior rises.
Any ideas? Thanks in advance!
My suggestion is to implement a callback system with interfaces. Each of your classes communicating with each other should implement these.
The classes should Register to the creating class.
Then they can call a method in the creating class which invokes the interface method of each registered class and passed the data this way.
This SO answer might help
https://stackoverflow.com/a/18279545
If you want to develop GUI applications, you should really get into the basic concepts. This can be very time-consuming, but it is necessary, otherwise you will encouter strange behaviour. I will just give you a basic understanding to answer your question.
You think of simple console applications, where you usually have a single thread and passing around objects is valid. With multiple threads, this is fatal, even with static variables. Each variable or object can be modified concurrently and the other thread may not be able to 'see' the changes in time. This is a complex matter, since there are also caches and separate stacks for each thread. In short, fc may not always be synchronized in App and sc, therefore reads and writes may be inconsistent.
What to do now? Learn the concepts of GUI programming. Often you do not even have to share objects for simple things. If a GUI control triggers an action, use a Listener, look here. If you want to access a database for example, then just make a new connection object for each request or button click, whatever. This is simple to start, add complexity later.
A simple variant to share objects is to use the synchronized keyword, which ensures that a method or a field is only accessed by one thread at a time. Here is an example. Also look at thread-safe data structures provided by Java (java.util.concurrent).
For advanced purposes you would have a separate thread and you would connect them with Sockets to pass messages or data.
Where should my user interface located in a simple CRUD application (with Java).
In my application I have the main class as well as another class which handles all the things which have something to do with the database e.g. getting information from it or adding new info to it.
Is it wiser to keep the UI-elements in the main class and leave the database class take the user input forward e.g. add a new element into database class, like this:
public static void main(String[] args) {
Scanner scan = new Scanner(system.in);
System.out.println("Give me your name:");
String name = scan.nextLine();
DatabaseHandler db = new DatabaseHandler();
db.addNameToDatabase(name);
}
Or should the input prompt exist inside the DatabaseHandler, so in the main-class only the method call is shown, like this:
public static void main(String[] args) {
DatabaseHandler db = new DatabaseHandler();
db.addNameToDatabase(); //user interface now inside addNameToDatabase method
}
It really depends on the size of your program. If your program is small and easy to read in one file then let it be so. As the program gets bigger then it becomes necessary for clarity to break it out. (If it is really small than a straight procedural way of coding might be the best within one class.)
In the case you break it out then the main class should be a driver for both the UI and data portions, which should be in different modules. You might want to look at different patterns like MVC or MVP on how to split it up.
As you can see there is no one way fits all. Large programs that are broken up into components/modules/packages are harder to get your arms around because of the wiring, but make it easier for a team to work on.
Always during development, remember - high cohesion and low coupling. For your particular question, think this way - in either approach, are you having high cohesion? No. Why should the database class handle user input? And why the main method should handle user input? No, both your ways are,well ideally, wrong.
But we seldom come across ideal situations. Your IO should be handled by another class and your database should be handled by another class,so should your UI. And inside these classes as well, each method should have a specific task. Use getters and setters,for instance, in your IO class,to get and set variables. Each method doing what it should do ensures high cohesion. And in this way, you end up ensuring low coupling as well,because your modules won't be interdependent. You might think - oh well, I can write all this in just one class and get it over with, but remember, this approach has a lot of advantage. In situations where the maintenance of your code has to be done by someone else, they would know by the names of classes and methods to know where to look for the issues. In situations where you have to look at your own code after ages, you wouldn't even recognize one word if you aren't organized in this manner.
Remember - high cohesion and low coupling FTW!
Ideally - your main should just be a starting point to your program, and nothing else.
First I would like to say that I have only worked with java for 1 month now. This is probly a pretty simple question. I searched and the classic fruit example did not make any sense to me. I spent hours looking at it and trying to figure out how to apply this to make it work. It does not make any sense to me because everyone explains how to get and set a property with 2 lines of code and no structure statements. I would really appreciate a breakdown in how to talk to non-static from static.
I would like to setText in text box in my OBD2nerForm class from a separate and static class.
public class OBD2nerForm extends java.awt.Frame {
/** Creates new form OBD2nerForm */
public OBD2nerForm() {
initComponents();
} ....................................
public String setText(String text){
this.jFormattedTextField1.setText(text);
}
I think I have a static reference to this instance of the form defined here..
public class Status {
public static OBD2nerForm form = new OBD2nerForm();
it is called from my main like this
public class obd2ner {
public static void main(String[] args) throws IOException {
Status.form.main(args);
Then when I try to call it.. Status.form.getText gives me the initial values when the form is created. When I setText, it does not change the one on the screen.
I am just displaying this to keep it simple. There are many other parts going on. I have a static monitor on a serial port and I want it to grab the next data to be sent from the text box and then increment it.
I just don't understand how to use a getter and a setter on a non-static. It's not quite doing what I need it to do. It seems like I am seeing one instance on my screen and it is using a new instance to perform the getting and setting.
I tried this as per an answer I received, but it did not work...
public class OBD2nerForm extends java.awt.Frame {
String X = "";
//Trying out the runnable method of incrementing the code
public String getNewScannerValueRunnable(){
Runnable doWorkRunnable = new Runnable() {
#Override
public void run() {
Status.form.getNewRotatingValue()
;}
};
SwingUtilities.invokeAndWait(doWorkRunnable);
return X;
}
I could really use some other suggestions. i just don't understand what has to happen here.
Your form is being created fine, and there's just one reference to it, and it's ending up in that static variable. All is well up to that point.
There's a 'secret' of Swing you need to be aware of: You cannot (visibly) change the properties of GUI objects from any thread other than the Swing thread, aka the Event Dispatching Thread.
The trick to doing it anyway is to pass the property-changing code as a Runnable to either of SwingUtilities.invokeAndWait() or SwingUtilities.invokeLater().
EDIT:
OK, let's back up. Your form is AWT based, not Swing based, so I'm afraid my advice on using SwingUtilities would probably not have helped you, even if you had implemented it correctly. I'll try to give more specific hints this time.
You've created a class OBD2nerForm that's an AWT form. That class has a constructor which calls initComponents to set up some GUI components on the screen.
The class also has a method called setText that will put its argument text into one of the fields on the form. That method is an instance method, i.e. it's not "static", as you'd call it.
You have another class, Status with a class field form. The initializer for form calls the constructor for OBD2nerForm. That will create an instance of the form and store it in form; but I haven't seen a show() or setVisible() call being made to the form to actually display it.
Here are the first signs of trouble:
public class obd2ner {
public static void main(String[] args) throws IOException {
Status.form.main(args);
Class names (like obd2ner) should start with capital letters; but that's a matter of style and convention, it's not what's causing you problems. Following the conventions helps other people read and debug your code, though.
The bigger problem is obd2ner.main() calling your form's main(). That could be made to work, but it's usually a sign that you're doing something wrong.
While nothing stops you from coding static main methods into as many of your classes as you want, only one of those main's can be started from the outside, i.e. when you run your application. The first main is essentially the 'boss' method for your program.
The "first main" usually instantiates and initializes a few objects. In a non-GUI application, main() may then start up a loop or some other control structure, wherein it will then orchestrate the actions of the other objects. In a GUI application, main() will usually just instantiate and then show the GUI, and then end; once the GUI is visible, all further program activity is triggered by actions the user performs on the GUI.
Without seeing your code, I'm guessing that Obd2nerForm.main() also instantiates Obd2nerForm, and shows it. So you probably indeed have one instantiated but invisible form hanging off Status.form and another one instantiated, visible and referenced from some variable in Obd2nerForm. If you want to influence that GUI, you need to make a reference to that form accessible.
Probably the simplest would be:
In Obd2nerForm, declare a public static Obd2nerForm form, and in Obd2nerForm.main, right after you call the constructor, copy the reference to the form into that variable. From then on, you can access the form and its methods using e.g. Obd2nerForm.form.setText().
A reminder, though: You seem to have two main()s, and this needs fixing. All the stuff that should be done at the beginning of the app's lifetime needs to be in one of those mains, not several.
Finally, look at this method call:
Status.form.main(args);
That's the syntax for calling a method on a particular instance. But Obd2nerForm.main is a class method (what you call "static"), and so there isn't "a particular one" to call, it's always just the one that belongs to the class itself. That's why the syntax to call a class method is something like
Obd2nerForm.main(args);
The compiler lets you get away with the way you wrote it, but it's not how it's usually done, and indicates some confusion.
There... I hope that gets you a little further along. If you still have problems, please post a more complete code sample to PasteBin and I'll take a look!
How much logic do you normally put in the main class? Should logic in the main class be at minimum, only instantiating other, specialized classes, and running all the tasks from there?
If you have any suggestions on this topic (or external articles), I'd appreciate it.
For small tools, I'm happy to have most or all of the logic in the main class - there tends to be less of a model to work with. (For very small tools, I confess I usually don't bother with unit tests. In particular, there's less benefit on the design side of things than there is if you're building something which will be a component in a larger app.)
For large scale apps, the main class is really just involved with setting things up and getting them in motion. If you're using a DI framework that can be very little code indeed; if you're not using dependency injection then the main class often acts as a "manual" dependency injection framework.
Should logic in the main class be at minimum, only instantiating other, specialized classes, and running all the tasks from there?
Yes. main method and its surrounding class should ideally be used only as an entry point to start the program. The mere existence of the surrounding class is just an artifact of the way Java programs are composed (everything must be inside some class), and there's no reason why it should contain other stuff in addition to the main method (but there definitely are reasons why it shouldn't).
When you get the interesting classes (those that form the actual program) separated, you open doors for all kinds of flexibility. Perhaps some of those classes could be used in some other projects. Perhaps some day you'll want to replace some of them with better implementations. Maybe you'll find a better order to instantiate all those classes - so just swap a few lines. Or how about executing lengthy startup loadings and instantiations in parallel threads? Just wrap some of them to suitable Executors. Good luck trying this with a 1000+ line main class.
This kind of flexibility matters for everything except maybe for 100-line elementary examples, prototypes and such. But given that even small tools tend to grow, why not do it correctly right from the beginning?
It's not so much a question of whether a class is "the main class". It's a question of how much logic is in the public static void main(String args[]) method. Ideally, it should contain very little logic. It should essentially construct one or two objects, and then call methods on those objects. One of those objects might be a this() - an instance of the main class, and that's ok.
You have to put the main() method somewhere - there's no need to create a special class just to hold that method.
As a general rule, try to avoid having too much in static methods - static methods can't be mocked for testing.
The main class should be an entry point to your program and should thus be relatively small. However this all depends on your actual program. If it's 50 lines long, it might be overkill to create two files for it.
As an example, consider the default Swing Application Framework Desktop Application as it would be generated by the NetBeans template, which is simple and short, and whose main() method is a single line that launches it:
public class MyApp extends SingleFrameApplication {
#Override protected void startup() {
show(new MyView(this));
}
#Override protected void configureWindow(java.awt.Window root) {}
public static MyApp getApplication() {
return Application.getInstance(MyApp.class);
}
public static void main(String[] args) {
launch(MyApp.class, args);
}
}