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.
Related
I am building a webcrawler which is using two classes: a downloader class and an analyzer class. Due to my design of the program I had some methods which I outsourced to a static class named utils (finding the link suffix, determining if I should download it given some variables, etc.). Since at a certain time there is more than one downloader and more than one analyzer I'm wondering whether they can get a wrong answer from some static method in the utils class.
For example, say the analyzer needs to know the link suffix - it's using the utils.getSuffix(link) method. At that same time the OS switches to some downloader thread which also needs to get some link suffix and again uses utils.getSuffix(link). Now the OS switches back to the analyzer thread which does not get the correct response.
Am I right?
In case I'm right should I add synchronized to every method on the utils class? Or should I just use the relevant methods in every thread to prevent that kind of scenario even though I'm duplicating code?
This entirely depends on the implementation of the method. If the method uses only local variables and determines the suffix based on the parameter you give it, all is well. As soon as it needs any resource that is accessible from another thread (local variables and parameters are not) you'll need to worry about synchronization.
It seems to me you're using statics as utilities that don't need anything outside their own parameters; so you should be safe :)
I'm starting with Android and wonder if background Task like DB reading and saving are always encapsulated in private classes?
I mean, at the moment I have:
private class SaveToDB extends AsyncTask..
private class ReadFromDB extends AsyncTask..
public void onButtonClick(View v) {
new SaveToDB().execute();
}
And so on. This way, I always have to create a new object if I want to execute background tasks. Is that the correct way?
What I wonder is that all my private classes are "actions" itself, not really objects. As they are named eg save or read which naming normally applies to methods by convention, not to classes.
Moreover, in case I'm doing it right: is it good practice to neast the private classes inside MyApplication Activity? Or should I refacter them out into own separate classes?
You could write a service to handle all the background content management. So, when you want to save, you just message the service and tell it to write data. This is much more complicated. For simple things, you can do it exactly as you are currently.
EDIT:
Also, as Ian pointed out, take a look at the new database interfacing classes post 3.0.
If you are firing of async tasks to interact with a sqlite database, then its not the best way to do things these days, you should check out cursor loaders instead.
http://developer.android.com/guide/topics/fundamentals/loaders.html
http://developer.android.com/reference/android/content/CursorLoader.html
Once you got your head around them they are much easier than firing off async tasks, infact they build on top of async tasks to address some of the issues you describe and are tolerant to configuration changes.
I highly recommend to move away from AsyncTask (for db access) and use the Loader API instead.
Its backported in the compatibility package so you can use them in older versions prior to Honeycomb.
Not always.
For example, if you've got a task that is to be used by different activities (I'm not talking about sharing the same instance), you will want a public class so you don't write it several times.
If you only use that (class of) task in one place, private class might help keeping your code cleaner.
It is a correct way for using AsyncTask, which isntance you can execute once.
Class Name can be DbSaver isntead of SaveToDb for instance which is more readable.
If that class is used only one Activity you can nest them, why not. But if you have task which is executed within different Activities, it is a good idea to create his own file.
It is good design to loosely couple your database access from your UI code. One way to avoid having to create a new object every time would be to make the database access classes a singleton and just return the instance of the class whenever you need to make a transaction.
To your last question it is a better idea to move the database management to its own class so that it can be accessed across several activities. If you do it all in a private class then what happens when you have a new activity that need s database access?
I have a GUI class with a menu of buttons and textfields. Depending on what choices that is made in the menu and the input, methods in the GUI class are calling methods in the Logic class to send the input and create new objects of Customer class and Account class and so on.
To be able to communicate between the GUI- and the Logic class, I first create an object of the Logic class and I do that inside the GUI class, since it's here I have my main method. It this the best way to do it? Do I need some kind of reference variable between GUI- and Logic class or just use the reference when the object was created in the beginning of the GUI class? I guess to be able to communicate with a class, it must be an object first!? Thanks!
Logic logic = new Logic();
logic.addCustomer(name, number);
Ideally you shouldn't directly create the logic class.
You should break down the functionality into a number of small classes, each of which satisfy a responsibility.
A simplistic way would be for the GUI class to create listeners which listen to the user events. In response the to the use event they fire events that your logic registers itself for. Then when the event is received the logic class can perform the functionality.
You should read about observer pattern, event driven design...
You can read about event driven programming here http://en.wikipedia.org/wiki/Event-driven_programming .
I would instantiate the Logic class outside the GUI, but pass it as an argument to the GUI constructor. It's nearly equivalent to what you are already doing, but I think it makes it clearer that the GUI uses a Logic object. Also, it's possible that Logic does some other things before/after the GUI starts/closes; it might not be the case now, but it could be true in the future if you extend your program.
Many other answers tell you to look at MVC, but that might be overkill for your project. It can decrease complexity for a large project, but increase it for a small one.
EDIT:
Logic login = new Logic();
...
MyGUI gui = new MyGUI(logic);
...
I would suggest you do some researches on the MVC architecture. Your GUI (view) shouldn't interact directly with your model (logic). Implement a controller that will get the "signals" from your view and will be in charge to create your "logic objects" and work with them.
You can create on object of type Logic in your main and store a reference of the object in your Window object - so you can access your Logic object as long as the window exists.
You should look up the Singleton design pattern for such trivial scenarios.
By default, Java uses Reference variables. Hence, if you instantiate your object in GUI class, make sure you send the object via method calls to your processing class.
Alternatively, you can look into singleton classes, which will return only one instance of the class. Inside that class, instantiate all the objects that you will need globally, and re-use that instance throughout your program.
Generally you can. If your application is very simple.
But this approach is not scalable. As your application gets more complex it became much harder for development and support. Try to consider Model–view–controller pattern to define a best way for your design. (according to your nick name I'll take a risk to propose an alternative link)
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);
}
}
Okay, I'm NOT a Java noob, it just so happens that I've forgotten a tad bit about core Java while I was learning more fun stuff like MySQL, Servlets, Java EE, JDBC etc etc; so don't frame your answers as if I were a beginner. Now the question.....
I'm writing a class (lets say ThisIsAJFrameExtendingClass) which extends JFrame, and to minimize confusion with my overall project, I also want to park some other utility methods in ThisIsAJFrameExtendingClass. I intend this class (ThisIsAJFrameExtendingClass) to seek certain inputs from the user following which; commit suicide (ie dispose()). So, my question is, how can I independently use the utility methods inside the class without any JFrame popping up on the user screen.
I'ld like a solution with the help of multiple constructors inside the ThisIsAJFrameExtendingClass class, where, invoking the argument-less constructor return JFrame and the second constructor with a boolean argument gives access to the utility methods.
[UPDATE]
Ohh.... I just had a thought, the utility method has a return type of ArrayList so, assuming the utility method is called utilMethod() then:
ArrayList<String> pring = new ThisIsAJFrameExtendingClass().utilMethod();
will the above code output any JFrame?
You could make the utility methods static, in which case they can be invoked using ThisIsAJFrameExtendingClass.<method name> without creating an instance.
The stuff about constructors doesn't really make sense to me. A class's constructor always returns an instance of that class. It can't return "something else" because of a parameter you pass in.
[Edited to respond to the question's Update]:
new ThisIsAJFrameExtendingClass() will create an instance of your class, running its constructor (and the default constructor of all superclasses). This may allocate other resources (such as other Swing components or whatever) that each constructor in the inheritance tree requires. So a JFrame is created, but if you only call utilMethod() and never hang on to the reference to the frame, it will be garbage collected and its resources freed at some point in the future.
Creating a JFrame instance to call a single utility method on it isn't a particularly efficient way to go about things, but it won't cause any problems. (As Chad says, by default a JFrame isn't visible, so users won't see anything if you're using it in "util" mode).
As to returning an ArrayList, as a general rule when using collections, you should return the highest level interface that makes sense rather than a concrete class. So in this case, consider returning List<String> or even Collection<String>.
I have a lot of trouble getting behind your concept, which sounds a bit confused to me. At the very least, it sounds like horrible design. But I do have some suggestions:
You can make those utility methods static, then you won't need to instantiate your class at all to use them. This would be the simplest case.
You could pack your utility methods inside a static inner class of your frame, which essentially gets you around the requirement to only have one class per file.
Finally, do you just want the JFrame to disappear once the user is done with it, or do you want to terminate the application? dispose() will do only the former, your app will continue to run as a kind of headless zombie process.
Okay let's assume the methods you need aren't static.
In that case, remember the JFrame won't show up unless you call setVisible(true); So just make sure you never show the frame, and you can use whatever functions you want without it annoying the user.
Or you could design it properly and break out the utility methods into a separate class...