I'm currently building a Java GUI application and I'm about to implement something that seemingly requires a great deal of thinking, at least for someone as relatively inexperienced as me.
The situation
is as follows: I have a class Customer at domain level, that holds a collection of jobs, which is a class too (Job). The application is for a fictious gardening company that wants to manage its customers and the jobs it does for them.
At GUI level, I have a jList for all the customers, with a custom listmodel that extends AbstractListModel. This part of my application works perfectly, I can add/edit/remove customers easily and as it should be.
The goal
now is to implement a jTable that should show the jobs for the customer selected in the jList.
No doubt I'll need a custom TableModel, the question is: where to get the data from? It should be noted that the collection of jobs in the Customer class is an ArrayList, and the class has no method that returns this ArrayList directly, it is only possible to get a copy, since I don't want it to be possible to mutate the collection in the class directly from a public context.
My idea
Is to let the tablemodel have a method to change the internal collection, with a customer parameter. When the index in the jList changes, that method should be invoked, so that the jTable represents the Jobs that have been done for the customer.
When I have to edit/create/remove a job, the changes are always done on the tablemodel first, which will propagate the changes to the customer object (in case of a new job or job removal).
The question
Is that a good way to implement it? I feel it is not, because if I forget to do any changes to a Job via the tablemodel, and on the Customer or Job directly, there will be inconsistency and trouble. Are there better ways? If it involves changing other stuff, I do not mind.
(optional) Small subquestion
I lack some knowledge on the different Collections in java. I usually just go with ArrayList, like in this case in Customer for (mutable) jobs. Is there a better collection for this?
Not saying this is the best way to implement this, but this is how I would do it
Make sure the customer Job list is observable. Either by using a 3th party lib which provides collections which fire events (I think Google has some available), or just make sure that every method on the Customer which updates the Job collection fires events
The table model representing the Jobs for a certain Customer can then listen for those events and update itself accordingly
It is unclear whether you allow to make changes to the table ui, but if you do, the table model should be responsible to propagate those changes again to the Customer
So nothing changes on your current edit/create/remove/add job code. That keeps working with your Customer and does not even know a TableModel exists. The TableModel works also directly against the Customer and does not even know there might be UI to edit/create/remove/add jobs. It just listens for any changes made to the job collection and updates itself accordingly.
It seems like a very bad idea to make the changes to the job list in all parts of your code through the table model. The Customer is your model, and the JTable is the view (MVC pattern anyone). The fact the JTable needs a different representation of your model (a TableModel) is a side-effect.
Related
I am working on my first Axon application and I cant figure out the use of the aggregates. I understand every time a command handler is called, the aggregate is being recreated by all the events, but I dont understand what other usage the recreating of the aggregates could have.
Like when should I manually recreate an aggregate?
What is the benefit of the aggregate being recreated every time I call an command?
The way I set up my application, I use a aggregateview to persist the data I need into the database. So now I feel like the events are just stored in the event store and are only used to recreate the aggregate after I call a command. Is there nothing else I should do with the events being stored and the recreation of the aggregate? Shouldn't I for example recreate the entire aggregate, instead of fetching the aggregateview out of my database by ID to update it.
The idea behind Event Sourcing your Aggregate, is that these events are the source for any model within your system.
Thus, if you create a dedicated Command Model handling the commands like you describe, then this model (which from Axon's perspective is the #Aggregate(Root) annotation class) will be sourced from the events it has published.
Additionally, you can introduce any type of Query Model you want; a RDBMS view, a Text-Based Search solution (e.g. Elastic), a time series database, you name it. Any of these Query Models are however still part of this same root application your Aggregate resides in. As you have the events as the means to notify others of decisions being made, it comes natural to (re)use those to update all your Query Models as well.
Now, it is perfectly true that you are not inclined to use Event Sourcing for your Aggregates in Axon, which from it's perspective is called a State-Stored Aggregate. If you do this however, you'll be back at having distinct models in distinct storage mechanism, without a single source of truth.
So, to circle back to your question with this added knowledge, I'd state the following:
Like when should I manually recreate an aggregate?
You are never inclined to recreate the Aggregate as the Command Model, ever, as the framework does this for you. If you have a mirrored Query Model Aggregate, then you would recreate this whenever you have added/removed/changed fields within the model. Or, if you have introduced entirely new models.
What is the benefit of the aggregate being recreated every time I call an command?
The benefit of recreating it every time, is the assurance that you will be using the latest state always. Even if between release of your application you have added/changed/removed new fields. The #EventSourcingHandler annotated methods would simply fill them in, without the need for you to for example write a database script to adjust it on the database level directly.
Concluding, the reason for this approach lies entirely within the architectural concepts supported through Axon. You can read up on them on AxonIQ's Architectural Concepts page if you want; I am sure it will clarify things even further.
Hope this helps you out #Gisrou8! If not, please come back with more questions, I'd gladly like to explain things further.
Update: Further Command Model explanation
In the comment Gisrou8 placed under my response it becomes apparent that "the unease" with this approach mainly resides in the state of the Aggregate.
As shared in my earlier response, the Aggregate as can be modeled with Axon Framework should be, in an Event Sourced set up, regarded as the Command Model in a CQRS system.
One of the main pillars around the Command Model, is that the only state it contains is the state required for decision making logic. To be more specific on the latter, the only state stored in your Aggregate is the state used to decide if a Command Handler should accepts the incoming command and publish an event as a result.
Thus, the sole fields you would introduce in your Aggregate along side the Aggregate Identifier are the fields you need to drive these decisions.
This is what the Command Model is intended for, so do not worry about this point.
To answer any queries within your application, you'd introduce a dedicated Query Model which is updated as a result of the events published by the Command Handlers within the Aggregate. It's this exact segregation which is the strong suit of this model as it allows for better scaling, performance improvements or required team separations, among other non-functional requirements.
I will usually have 5-6 events per aggregate and would like not to store projections in DB. What would be the easiest way always to make view projection at query time?
The short answer to this, is that there is no easy/quick way to do this.
However, it most certainly is doable to implement a 'replay given events at request time' set up.
What I would suggest you do exists in several steps:
Create the query model you would like to return, which can handle events (use #EventHandler annotated methods on the model)
Create a Component which can handle the query that'll return the query model in step one (use a #QueryHandler annotated method for this.
The Query-Handling-Component should be able to retrieve a stream of events from the EventStore. If this is based on an aggregateIdentifier, use the EventStore#readEvents(String) method. If you need the entire event stream, you need to use the StreamableMessageSource#openStream(TrackingToken) method (note: the EventStore interface implements StreamableMessageSource)
Upon query handling, create a AnnotationEventHandlerAdapter, giving it a fresh instance of your Query Model
For every event in the event stream you've created in point 3, call the AnnotationEventHandlerAdapter#handle(EventMessage) method. This method will call the #EventHandler annotated methods on your Query Model object
If the stream is depleted, you are ensured all necessary events for your Query Model have dealt with. Thus, you can now return the Query Model
So, again, I don't think this is overly trivial, easy or quick to set up.
Additionally, step 3 has quite a caveat in there. Retrieving the stream of a given Aggregate based on the Aggregate Identifier is pretty fast/concise, as an Aggregate in general doesn't have a lot of events.
However, retrieving the Event Stream based on a TrackingToken, which you'd need if your Query Model spans several Aggregates, can ensure you pull in the entire event store for instantiating your models on the fly. Granted, you can fine tune the point in time you want the Event Stream to return events from as you're dealing with a TrackingToken, but the changes are pretty high you will be incomplete and relatively slow.
However, you stated you want to retrieve events for a given Aggregate Identifier.
I'd thus think this should be a workable solution in your scenario.
Hope this helps!
I am trying to implement MVC for my Java desktop application and I am not very familiar with it. For the purpose of the question, I am considering a use case in which you click "refresh" button, it queries DB for list of students and update students lists. Here are my questions that have been confusing me:
1-For querying the DB, does it happen in the controller or in the model? My gut feeling says its controller who queries and once results are received, it updates the model. However I read in many posts that the Model is the one who knows its state transitions and does its updates!
2- Who creates the the view and model? Does the controller create them or are they created externally and passed to the controller?
3-In the above use case, does the model consists of an ArrayList of Students or is the model just a Student object but the Controller has and ArrayList of models?
Please help a fellow developer
For querying the DB, does it happen in the controller or in the model?
Short answer, querying the database happens in the model.
A List of Student is the model for the GUI, where Student is a Java object containing the student information. The list of students is also the model for the database.
There are different ways you can approach the interaction between the list of students and the database. One way is to read all of the student information at the beginning of your GUI initialization. As your users interact with the GUI, your GUI controller inserts, updates, and marks students for deletion in the GUI model. Finally, when the user closes the GUI, you write all of the changes in the list of students to the database. This way, while simple, exposes you to data corruption if your GUI abends. Also, only one person can make changes to the database at a time.
A better way is to read all of the student information at the beginning of your GUI initialization, as before. As your users interact with the GUI, the GUI controller updates the list of students in the GUI model. After each insert, update, or delete, you call the appropriate methods in the data access object to insert, update, or delete the student information, respectively.
Who creates the the view and model?
You do. :-)
The model / view / controller pattern is not just for organizing code. Generally, you create the first cut of the model first. Then you create the view, and add the fields to the model that you forgot when you created the first cut. Lastly, you create the controller. The controller(s) should do nothing but execute methods in the model to update the model and methods in the view to repaint / revalidate the view.
You pass an instance of the model and an instance of the view to your controller(s). You should only have one instance of the model and one instance of the view. However, they are not singletons.
In the above use case, does the model consists of an ArrayList of Students or is the model just a Student object but the Controller has and ArrayList of models?
Finally, an easy question. Neither.
Your model is a List of Student. The List interface will be implemented by the ArrayList class. Something like this.
List<Student> studentList = new ArrayList<>();
By using the interface, you can easily change the ArrayList to a LinkedList, or your own implementation of the List interface.
A general Java rule is to use the interface unless the methods you need are only defined in the concrete class.
I hope this was helpful.
In my application I have some similar threads doing their stuff and I'd like to represent some of their properties in a row of a table (one thread per row). I'd pass a row object to corresponding thread and update them on changing values, but I couldn't find anything like that in API. So what is the right strategy to keep rows updated with actual properties?
Using a JTable, the traditional way to create such a table would be to have a class implement TableModel (or extend AbstractTableModel or DefaultTableModel). There you would maintain your data, and do so in such a way that it is easy for you to look up a data structure per Thread. You would implement the getValueAt method to return the values for your Threads per row. to When a Thread's properties change, it would then go an update the TableModel. Then you would need to tell your JTable that your data has changed and have it update from the model. You would do this by firing a tableChanged event. AbstractTableModel and its descendants have variety of fireTableChanged-type methods available. Make sure you do this firing of events in the EventDispatchThread. See topics on currency in Swing and the SwingWorker for info on worker threads interacting with painting GUIs.
Take a look at binding apis, e.g. the JGoodies binding api.
I've found a sample for a sorted JList, but my application is powered by an embedded H2 database so I'm wondering if there isn't a better way to implement this with that in mind. Especially considering the table in question could become enormously large, and duplicating all that data in a JList's list model seems to kinda defeat the point of having a database to manage it.
Is there a good way to do this? Or am I forced to cobble together some clumsy hack to allow the JList to "scroll" through dynamically queried chunks of data or something?
Your JList's ListModel is responsible for exposing the backing data as an ordered list. ListModel's methods will be called by JList from the UI (AWT event) thread, so its performance needs to be pretty good. This is why most implementations have the ListModel's backing data in memory. I suppose you could implement ListModel with your database as the backing data. You'll most likely extend AbstractListModel to get the listener registration, and implement getElementAt(int) and getSize(). getElementAt would then be responsible for getting the object for a particular index. Keep in mind that JList will call getElementAt many times for different indices, so you may find yourself caching the results. Depending on how much data you're caching, you might just retrieve the entire dataset from the database.