How to put DAO and GUI together with MVC - java

I'm creating a Java Application that represents a school. My aim is to keep the application open for new features, so I'm trying to apply some Design Patterns to it.
What I have so far is a HSQLDB connected to my program.
In the database one can store
pupils
courses
years
exams
grades
The current structure is as follows:
there are classes for each of the objects that contain the attributes + setters and getters
for each object there is a DAO that manages the CRUD operations on the DB
each DAO implements a GenericDAO interface
If i want to create a new pupil i can call:
PupilDao pupil = new PupilDao();
pupil.connectToDB();
pupil.add(new Pupil(name, age,...));
pupil.disconnectDB();
Every DAOs connectToDB() and disconnectDB() methods point to a DBuser-Classes connect() and disconnect() methods. So if I want to change the connection, there's only one place to do so.
So far, those operations work.
My questions are the:
1.) Is the current design a proper use of DAOs? I'm asking because i would rather have one
Dao for all objects because right now there's a lot of repetitive code in the DAOs. (e.g. get, update, delete...)
Now that the DB-Access works, I want to create a GUI using Swing. I have some experience doing this although not with the MVC-Pattern.
2.) As far as I understand, the DAOs + my object classes would be the Model here. Is that correct?
3.) My understanding of MVC is that in my View-Class (i.e. the GUI) I set listeners for my actions which point to different Controller-Classes implementing the ActionListener interface and in my Controller-Classes I would for example have a actionPerformed() that creates a new Pupil (using the DAO / Model - Classes). Am I on the right track here?
4.) Is it favourable to have one big Controller managing all actions over having different Controllers?
I'm asking those questions because I read/watched a lot about patterns/OO-Design and want to make sure my understanding is correct.
Furthermore I highly appreciate your thoughts on my design! What could be done more flexible or better to maintain later?
Thanks in advance for every suggestion and sorry for the somewhat long explanation!
Felix

While I still can't answer my questions for sure, I think I found a suitable way
for me and want to share the design (suggestions/answers are still appreciated!).
1) The applications entry-point is the main-application class (MVC.class). This class creates the
view using a main-controller. Here's the code:
public static void main(String[] args) {
// view is declared as class-variable
view = new View();
MainController mcontroll = new MainController(view);
view.getFrame().setVisible(true);
}
The main-controller only takes the view as parameter as its only purpose is to display the view.
As stated in my post above my aim was to display different database tables from a HSQLDB and modify them.
2) In the menubar there are entries for managing years, courses, etc. If one entry is clicked, the controller for the clicked category (e.g. years) takes control. Here is, how the controller is changed:
public void addManageYearsListener(ActionListener listener) {
mntmYears.addActionListener(listener);
}
The above method is located in the view class (i.e. the GUI class) but the main-controller implements the actionPerformed()-method. To do that, the main-controller calls the method defined in the view in his constructor like that:
public MainController(View view) {
this.view = view;
this.view.addManageCoursesListener(new ManageCourses());
this.view.addManageYearsListener(new ManageYears());
}
The corresponding class "ManageYears" is then defined as inner class:
class ManageYears implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
MVC mvc = new MVC("years");
}
}
What happens here is that when the menuitem is clicked, the main-controller "hears" the click (cause he is listening to it) and calls the main class again, although this time with a string as parameter. The constructor of the main class checks the string and sets the model and the controller that is needed. See here:
if (controller.equals("year")) {
YearDaoImpl yearDao = new YearDaoImpl();
YearController ycontroller = new YearController(view, yearDao);
}
"controller" is the string that is passed with the constructor and "yearDao" is the Data Access Object that handles the CRUD-operations which have to do with the object "year" (which is a class itself).
So now it's possible to switch controllers at runtime.
3) The year controller sets the ActionListeners for a add and remove button in his constructor (just like the main controller did for the menu item), get's the data from the database (via the yearDao) and sets the table model in the view (view has a setTableModel()-method for that) passing the returned ResultSet as parameter of the table Model class:
public void showYears() {
try {
con = yearDao.connectToDB();
stmt = con.createStatement();
rs = stmt.executeQuery("SELECT * FROM YEARS;");
view.setTableModel(new YearTableModel(rs));
con.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
As you can see, the yearDao has a connectToDB()-method that returns a connection (the connection is actually gotten from a c3p0 connection pool) which is then used to get a ResulSet of years from the database. The setTableModel()-method is then called setting the YearTableModel - a custom class extending AbstractTableModel and passing the ResulSet as parameter.
With the explained design it is now possible to:
1.) only have one table in the GUI that is populated with different database outputs.
2.) seperate the view from the data (which is what this whole fuss is about ;-)).
3.) add new controllers or models when needed without changing a lot of code.
As mentioned at the beginning I still appreciate every suggestion or improvement!
If you made it till the end of this post, I hope you found something to use in your own program!
regards,
Felix

Related

Can you build a Swing GUI for an MVC-style game if the Controller doesn't have a reference to the Model?

I couldn't find any similar answers on here, but apologies if this it too specific to my own problem.
I am building a simple game using in Java that has both a command line interface and a GUI (activated using a command line flag). The way that the game is written is that the game logic (Model) has a reference to the input (Controller) and the output (View), but neither the input or output have a reference to the model (this was a requirement). The flow of the game is therefore controlled by a loop in the application model similar to:
while (!gameFinished) {
InputType in = input.getUserInput(); //1
performAction(in);
}
Now that I am trying to build a Swing GUI for this (not something I have experience in), I am struggling to see how it could work with event listening. It would ideally work in the way that when a button is pressed (new game, save game, exit game etc.), an InputType would be sent to the Model (essentially doing the same that the commented line does) to be handled accordingly. But if it doesn't hold a reference to the Model, it can't 'send' the InputType. I suppose I am looking to build a GUI that works with the Model 'asking' for input, rather than 'listening' for it.
Is this possible? And if so, can anyone provide me with any useful resources for solving this? If not, an explanation or potential alternative solution suggestion would be appreciated.
I'm not gonna go into whether your flow is right or wrong.
Create an event queue in input. Listeners can then add events to the queue. Model can then ask the Input whether there are unhandled events in the queue and perform an action depending on the event that occurred. Let model hold a reference to the view interface call the appropriate view method in the performAction method.
Pseudo code:
class Controller{
Queue<UIEvent> events;
void setupUI(){
button.addEventListener( new EventListener(){
Model.this.events.add(new TappedButtonEvent());
});
}
UIEvent dequeueEvent(){
if(events.size() > 0){
return events.pop()
}
return null;
}
}
class Model{
public void loop(){
while (!gameFinished) {
UIEvent in = input.dequeueEvent();
if(in != null){
performAction(in);
}
}
}
}
Do not encapsulate how something is displayed in Model, let view handle it.
interface View{
void displayExitMessage()
}
class CommandLineView implements View{
void displayExitMessage(){
this.commandLine.append("Are you sure you want to exit(Y/N)?");
}
}
class CommandLineView implements View{
void displayExitMessage(){
this.window.showDialog("Are you sure you want to exit?", Button.YES, Button.NO);
}
}

java MVC application

i'm creating an application at the moment that i want to reuse the GUI so to make it easy to reuse and change the elements I've been using the MVC design pattern but im having a few issues with it the first issue is how to implement the actual design pattern as different examples implement it in different ways. this is the code i have in my main, does this look ok.
mainView theView = new mainView();
mainModel theModel = new mainModel();
mainController theController = new mainController(theView,theModel);
theView.setVisible(true);
The second problem i have was the example set up was the controller implemented a view in the by using the following code:
controller:
this.theView.addCalculateListener(new CalculateListener());
view:
public void addCalculateListener(ActionListener listenForCalcButton){
calculateButton.addActionListener(listenForCalcButton);
}
this seems to work fine but i have problems implementing listeners in the JMenu as there added within the constructor of the view so my plan was to create the JMenu in an external class where i can put all the menu items as global variables (to clear up code) which will allow me to add the listeners in this manner, is this an OK solution or am i way off.

How to model POJO from Vaadin UI? (Best practice)

I am working on a PDF Invoice generator in Vaadin 7. The code as it stands at the time of this writing can be found here. The repo includes a crude class diagram.
My question concerns the best practice of collecting the user input from the TextField and other Vaadin components to create an instance of Invoice.
Currently it works like this:
When the user clicks the button to generate the pdf, the class VaadinInvoiceGui (a Panel) calls the method createPdf(VaadinInvoiceGui gui) in the class VaadinInvoiceController.
VaadinInvoiceController calls method getInvoiceFromForm(VaadinInvoiceGui gui) in class InvoiceMapperImpl.
InvoiceMapperIml creates and returns an Invoice (POJO) by calling get methods in the VaadinInvoiceGui that gets passed to it. These getters return the values of the components in the view.
VaadinInvoiceController takes the Invoice returned by InvoiceMapperImpl and goes on to create pdf from it etc..
The getters in VaadinInvoiceGui look like this.
public String getCustomerName() {
return infoPanel.getCustomerNameTextField().getValue().toString();
}
public String getCustomerStreet() {
return infoPanel.getCustomerStreetTextField().getValue().toString();
}
public String getCustomerCity() {
return infoPanel.getCustomerCityTextField().getValue().toString();
}
...
I really don't feel like it's a good idea to pass the whole gui class to the controller and especially to the mapper, but I'm not sure what would be a better way of doing it. I could change the method createPdf(VaadinInvoiceGui gui) to something like createPdf(String customer name, String customerStreet, ...) but the number of parameters of the method would grow huge. I could do it using setters but then it would basically be doing the object mapping in the gui which doesn't seem like a very clean idea either.
What is the proper way of doing this?
Write a bean for the data to pass around as your model. Then use the FieldGroup to bind between model and form. Wrap the model as BeanItem<Model>. Binding is either done by name (convention) or by annotation #PropertyId.
master-detail-example: https://vaadin.com/wiki/-/wiki/Main/Creating+a+master-details+view+for+editing+persons
general infos: https://vaadin.com/book/vaadin7/-/page/datamodel.html
binding in forms: https://vaadin.com/book/vaadin7/-/page/datamodel.itembinding.html

Using Stripes, what is the best pattern for Show/Update/etc Action Beans?

I have been wrestling with this problem for a while. I would like to use the same Stripes ActionBean for show and update actions. However, I have not been able to figure out how to do this in a clean way that allows reliable binding, validation, and verification of object ownership by the current user.
For example, lets say our action bean takes a postingId. The posting belongs to a user, which is logged in. We might have something like this:
#UrlBinding("/posting/{postingId}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
Now, for the show action, we could define:
private int postingId; // assume the parameter in #UrlBinding above was renamed
private Posting posting;
And now use #After(stages = LifecycleStage.BindingAndValidation) to fetch the Posting. Our #After function can verify that the currently logged in user owns the posting. We must use #After, not #Before, because the postingId won't have been bound to the parameter before hand.
However, for an update function, you want to bind the Posting object to the Posting variable using #Before, not #After, so that the returned form entries get applied on top of the existing Posting object, instead of onto an empty stub.
A custom TypeConverter<T> would work well here, but because the session isn't available from the TypeConverter interface, its difficult to validate ownership of the object during binding.
The only solution I can see is to use two separate action beans, one for show, and one for update. If you do this however, the <stripes:form> tag and its downstream tags won't correctly populate the values of the form, because the beanclass or action tags must map back to the same ActionBean.
As far as I can see, the Stripes model only holds together when manipulating simple (none POJO) parameters. In any other case, you seem to run into a catch-22 of binding your object from your data store and overwriting it with updates sent from the client.
I've got to be missing something. What is the best practice from experienced Stripes users?
In my opinion, authorisation is orthogonal to object hydration. By this, I mean that you should separate the concerns of object hydration (in this case, using a postingId and turning it into a Posting) away from determining whether a user has authorisation to perform operations on that object (like show, update, delete, etc.,).
For object hydration, I use a TypeConverter<T>, and I hydrate the object without regard to the session user. Then inside my ActionBean I have a guard around the setter, thus...
public void setPosting(Posting posting) {
if (accessible(posting)) this.posting = posting;
}
where accessible(posting) looks something like this...
private boolean accessible(Posting posting) {
return authorisationChecker.isAuthorised(whoAmI(), posting);
}
Then your show() event method would look like this...
public Resolution show() {
if (posting == null) return NOT_FOUND;
return new ForwardResolution("/WEB-INF/jsp/posting.jsp");
}
Separately, when I use Stripes I often have multiple events (like "show", or "update") within the same Stripes ActionBean. For me it makes sense to group operations (verbs) around a related noun.
Using clean URLs, your ActionBean annotations would look like this...
#UrlBinding("/posting/{$event}/{posting}")
#RolesAllowed({ "USER" })
public class PostingActionBean extends BaseActionBean
...where {$event} is the name of your event method (i.e. "show" or "update"). Note that I am using {posting}, and not {postingId}.
For completeness, here is what your update() event method might look like...
public Resolution update() {
if (posting == null) throw new UnauthorisedAccessException();
postingService.saveOrUpdate(posting);
message("posting.save.confirmation");
return new RedirectResolution(PostingsAction.class);
}

Badges implementation issue

I am designing a website using JSF + EJBS + JPA, etc. JAVA EE 6 to sum up.
You can create an article, and over time if it meets certain conditions (say 1000 views) it's awarded a "1000 views badge."
The problem arises when I want to create new badges dynamically. I have a badge entity class, and all badges are fetched from a database. How can I dynamically establish conditions for a badge to be awarded to an article, since the behavior depends on each instance rather than its type?
For instance the business logic for evaluating the meeting requirements for a '1000 views badge' is very different from the one used in a 'best rated article of the week' etc. Also, what if the number of badges grows?
I can't just extend a class because it doesnt make sense, so I figured I'm not looking at this the right way.
Any thoughts on how would you implement it?
Implement a #Singleton, which has a method running once in a period(once per hour or per 24 hours). It will have a collection of classes to check the posts for some conditions. If you want a new badge, just add a class.
#Singleton
public class Watchdog implements Serializable {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The em. */
#PersistenceContext
private EntityManager em;
private List<PostChecker> checkers = new ArrayList<PostChecker>();
#PostConstruct
public void init() {
checkers.add(new ThousandViewChecker());
checkers.add(new PopularPostChecker());
....
}
#Schedule(...)
public void monitor() {
for (PostChecker checker : checkers) {
checker.check(em);
}
}
}
If you don't want to add a class each time, create some xml file with the rules of badge awarding and create a factory of checkers, which will construct their badge rules using those xml files. Then to add a badge you will need just to add an xml.

Categories

Resources