So for my current project, there are basically three main Java classes:
GUI
Instant Messaging
Computation
Essentially, there needs to be full communication, so we've decided to use the mediator approach rather than than allow the GUI to run the entire project.
Basically, the mediator is going to encapsulate the communication. The problem we've run into is how to allow the GUI components to update without building a ton of methods for the mediator to call anytime something completes.
Ex. Say the GUI wants to log in the user, it goes through the mediator to create a thread and log in, but then the mediator has to relay the success/failure back to GUI as well as update a status message.
The other issue is things that need to update the GUI but do not need the moderator. Is it practical to just allow the GUI to create an instance of that class and run it or should everything go through the mediator?
Our original design just had the GUI managing everything, but it really killed reusability. Is there a better design method to use in this case?
If you're finding Observer to bring too much overhead, Mediator may be the best way to go. I definitely think that you shouldn't have the GUI run the show. If you're going to use the Mediator pattern, the mediator itself should be in charge. Something you might consider is a variant of the Command pattern. If you were using Ruby, I might recommend passing function callbacks around as a means of avoiding having the mediator contact the GUI for every little thing. But since it's Java, some form of encapsulating an action in Command pattern style may help.
If you don't want the callback/notification to be triggerd by the mediator, you can inject the callback into the login function and have login call it when it finishes.
I don't know how you would go about injecting the callback in Java, though. In a language where functions are first class citizens, you could just pass the function, but you're in Java so I guess you will have to use the command pattern as kmorris suggested.
You might also try having the GUI give the mediator a callback object that handles retrieving return values or setting whatever values you need (a version of the Command pattern). There would then be one per call from the GUI to the mediator.
Another thought is to group the methods the mediator calls into semantically related chunks. In particular if the mediator has sections where it tends to call several GUI methods in a row:
gui.a()
gui.b()
gui.c()
you can create a single method that handles the result of calling all three. The advantage of semantically grouped methods (i.e. setFileInformation over setFileMenu, setTab, etc.) is also then if you need to change the GUI, the contents of the methods might change, but the call the mediator makes may not.
Related
Within Java you can create an Observer-Observable set of classes in which the Observable can call the Observer. You can also in java explicitly reference an owning class instance in a child instance of another class and call the owning class instance's public functions.
Which is the better approach to take? Which is more beneficial in different scenarios, one example being Multi-Threading?
The Observer Pattern should be used whenever you don't know or don't care who is observing you. This is the key-concept in event-driven programming. You don't have any control of who is observing or what they do when you broadcast your events. Like you already mentioned in your comments, this is great for decoupling classes.
An example of a usage could be in a plugin-architecture:
You write a basic mail-server that broadcasts whenever a mail is received. You could then have a spam-plugin that validates the incoming mail, an auto-reply service that sends a reply, a forward service that redirects the mail and so on. Your plain mail server (the observable) doesn't know anything about spam, replies or forwarding. It just shouts out "Hey, a new mail is here" not knowing if anyone is listening. Then each of the plugins (the observers) does their own special thing, not knowing anything about each other. This system is very flexible and could easily be extended.
But the flexibility provided by the Observer Pattern is a two-edged sword. In the mail-server example, each plugin handles the incoming mail in total isolation from each other. This makes it impossible to setup rules like "don't reply or forward spam" because the observers doesn't know about each other - and even if they did, they wouldn't know in what order they are executed or has completed. So for the basic mail-server to solve this problem, It'll need to have references to the instances that does the spam/reply/forward actions.
So the Observer Pattern provides flexibility. You could easily add a new anti-virus plugin later, without having to modify your plain mail server code. The cost of this flexibility is loss of control of the flow of actions.
The reference approach gives you total control of the flow of actions. However you would need to modify your plain mail server code if you ever need to add support for an anti-virus plugin.
I hope this example gives you some ideas of the pros and cons of each approach.
In regards to multi-threading, one approach isn't favorable over the other.
I am looking for advice in structure rather than particular coding.
My program has a Main class that initializes a GUI and then, after puting the name of the files that are going to be read, I click one button. I attached a listener with the respective mouseClicked event handler and I do all my routines INSIDE the handler.
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
Is it usual to do things this way?
UI programming is event-based in Swing. Twisting it into any other style will not make it easier for you. What you might mean is that you should minimize the code in that UI part.
This means that you shouldn't tie the UI to the logic, therefore creating dense coupling. In this example, the file-reading code should be moved into another method, ideally in another class.
All my program inside an event handler?
To answer this specific question: No, that'd be terrible! It's okay to invoke your program from there, but don't write the code in the event-handler!
This doesn't seem a good approach, is it? Is it usual to do things this way? All my program inside an event handler?
You are right, this isn't a good approach. Instead look into implementing a Model-View-Control (MVC) type structure or one of its variants.
The Model: this is the brains of your program, the one that holds the program state. This should contain no GUI code, no listener code, just the data and the logic that goes with the data. The model should not implement a handler interface
The View: this is the GUI, here your Swing components and related code. The view should not implement a handler interface.
The Control: this is the connecting code between the two above, the code that handles user interactions, asks the model to change state. This may implement a handler interface, or have inner classes that do, or be composed of objects that do. Your control for instance could read in the file (in a background thread), supply the text to the model, and then the model could notify the view (or the control -- there are many variants of this) that its state has changed.
As an aside: don't give a JButton a MouseListener. Use an ActionListener instead.
There is no rules but only good practices.
And from Good Practice ethics, it is always advised to divide your code into small chunks, each one responsible for some stuff.
So you would better move your code outside the event handler and delegate the job to some method called readFiles() and call the later within your handler.
And even if this method can be cut into pieces you can do the same, e.g. it can only iterate over the files to be read and call a readFile() method for each one:
private void readFiles(Files[] files)
{
for(File file : files)
{
readFile(file);
}
}
Just a simple snippet and all should be updated to follow your model.
Firstly instead of providing a path to the file you can use
JFileChooser to do file selection operations. Especially since you
are using Swing.
Secondly one should attempt to modularize the code to an extent it
makes code looks simpler a d understandable. So you can create a
separate method that handles your file operations. The you can call
this function from any event handler. Be it mouse or keyboard. This
will avoid code duplication and will enable module reude.
I need to create a Playlist, I want to separate code/logic and GUI by using two classes:
Playlist (code/logic)
PlaylistGui (GUI)
It shall be possible to use the Playlist class standalone, e.g. in some kind of command line environment. The question now is, how would one plug both classes together, when using a GUI? My ideas until now:
Expose an observable list from the Playlist class, create a method setItemSource(Playlist source) on the PlaylistGui class
Not sure if possible in Java, just know this from .NET: Let Playlist class fire events and let PlaylistGui catch them, should lead to uncoupled code? :-)
Open for new ideas :-) Note I am using Java 7 and JavaFX, though I guess JavaFX doesn't limit possiblities, just extends them.
Events in Java:
http://castever.wordpress.com/2008/07/31/how-to-create-your-own-events-in-java/
Other alternatives are:
Java Delegates?
or both as separate processes with communication via sockets
Have a look at FXML, Controllers and the SceneBuilder tool.
I think your basic concept is sound, delegation of responsibility.
I would create an interface of the model, exposing only those methods you think that any basic controller/viewer would want. This means you can change the implementation without effecting any of the components that rely on it.
Listeners are, essentially, just a call back mechanism, where interested parties register themselves (through a common interface) to be notified when something occurs that they are interested.
Take a look at Writing Event Listeners for more information.
I would basic start out with a common library which defines the basic interfaces that all parties would need to know out (such as the PlayList and listeners).
This would allow to design 'n' implementations of the playlist based on your needs
I have a Java Swing application. I want to upload information to a web endpoint, and that process will take enough time to justify spinning off the work onto another thread. I'd like to use the Swing SwingWorker paradigm to do that. I'm confused on where I should be extending the SwingWorker.
Right now I have a single class for each web endpoint, and that class stores all the data destined for that endpoint, as well as the code necessary to interface with the endpoint (housed under a method called upload()). Should these classes implement SwingWorker since all the data is there that it needs to perform its task? Or should I have a secondary class FooWorker implement SwingWorker, that will call Upload() off of an internal Site object?
If I make a secondary FooWorker class, then it seems like I have to go to some trouble to stuff references to the Site into each FooWorker object that I instantiate (one thread/worker for each web endpoint), but that the Site won't be polluted by a bunch of SwingWorker methods and code.
If I extend SwingWorker with the Site class, then I can just call .execute() directly from the EDT for each Site which is much cleaner, to me, than creating a worker for each site, and then having that worker call upload() off the site.
Just looking for opinions and ideas about which approach is better. The Site class is already fairly complicated, and I'm afraid of putting a bunch of domain unrelated stuff into it if I extend the SwingWorker class. But the FooWorker class, if I go that route, will basically just be a thin wrapper around the Site class. Is that wrapper worth the trouble of keeping the Site class focused only on its own domain methods/data?
It is always a good idea to introduce abstractions where it makes sense. In this case, I'd say it makes sense because you might end up creating several SwingWorker classes.
What you could consider is to create a single SwingWorker class called, say, SiteWorker. Then, I'd create Site interface which implements the method upload(). Each class representing a connection to a site endpoint would implement this Site interface. You could then simply have SiteWorker to deal with the Site interface instead of you having to deal with all different sorts of Site classes implementing SwingWorker.
Remember, program to interfaces and not implementations. It makes your life easier if you can just create a single SiteWorker and then concentrate on the various site implementations.
Thus, you could pass the Site instance (which would be any class implementing Site) as an argument to the SiteWorker class, which would then, in its doInBackground() method simply call the upload() method of the instance implementing Site.
I have a class which extends JFrame and forms the GUI of my program. I want to use the GUI for two main purposes:
I want the user to be able to input values to the program.
I want the GUI to display values created by my program.
Considering my class has a lot of GUI elements, the source file is already rather large and It does not seem like good practice to bundle all the program code in with the GUI code. I'm wondering what is the best way to structure my code? I believe there is an issue where requirement 1 creates a dependency from the GUI to the program code, and the second requirement does the opposite.
So, I want one class for my GUI which contains all my GUI related tasks. I then want another class for my program logic. I should then be able to call methods from the program logic class from the GUI and vice versa.
Sounds like you are looking for a textbook MVC (Model-View-Controller) design pattern. I recommend you google "MVC Design Pattern" for summaries and use cases. That being said, you might want to put your program logic into a "Singleton" class (again, google "Singleton Design Pattern"). A properly implemented Singleton should be accessible from any other class in your code.
Consider also a third middle class which acts solely for data storage, you put values into it for storage, and you fetch values from it for work. This now creates 3 clear segments for your code, the Data (the Model), the GUI (the View), and the logic (the Controller). Voila, you've just implemented the MVC (Model-View-Controller) design pattern...
The business logic should not depend on the GUI logic.
Have your GUI take inputs from the user. Call business logic methods with these inputs as method arguments, and use the values returned by the methods to display the result in the GUI. The GUI thus depends on the business logic, but the reverse is not true.
If the business logic must callback the GUI, it should do so via well-defined GUI-agnostic callback interfaces, or listeners. For example, you could register a ProgressListener on some business logic object, and this object would call back the progress listener. The GUI would have an implementation of the ProgressListener which would in fact update some progress bar or text area. But the business logic only depends on the interface, and not on the specific implementation.
I'm not sure there is one "best" way to structure GUI code. As a general rule though, you should follow MVC. Your program (Model) should never directly depend on your View code. What it's allowed to do is notify the controller that the model (or parts thereof) changed, and that whichever views are currently displaying said part of the model should be updated.
Swing already provides this abstraction layer for some of its types of component, most of the classes are (somewhat confusingly) suffixed with Model. A simple example you could look at would be BoundedRangeModel. There should be only one instance of such a Model for every "unit" of data your program manages, and different views displaying this data should share this instance. Your business code manages this object, and whenever this piece of data changes, the GUI is notified using it by firing off some event listeners.