I am coding GUI application for exchange and synchronize data between company's Accounting software and e-commerce system (internet shop).
I want to create it using MVC (Model-View-Controller) Design Pattern.
Part of my application is function which overwrite e-commerce inventory balance with this from accounting software.
I've got
View - JDialog presenting progress of overwriting.
Controller - responsible for interaction between db's and view
Model - data from dbs and app's settings
When I queuing the database I must catch an exception (ClassNotFound and SQL).
Where I should create try {} catch {} block? In View? or in Controller?
I want to present some JOptionPane with error message and finish some state of application.
You have mentioned only checked exceptions.
You don't need to catch an exception. You can choose to declare it instead.
If you don't want to declare it, you can wrap it in a RuntimeException.
All exceptions from the model should be handled at a single place in code (so-called exception barrier) and presented to the Controller in a unified fashion. The Controller's main interest is whether the operation did or did not succeed, it's not interested in the fun details of why it may have failed.
Writing your DAO layer (for DB communication) without using something like Spring for declarative transactions, connection pooling, etc. is not recommended.
This is a tricky question and is going to come down to how you structure your code. Generally, if you can, have your models throw the exception in such a way that the view can handle it. This decouples you model from your view.
There are going to be occasions (such as using JTables or JLists) where this kind of thing isn't possible. In these situations, if possible, load the "model data" separately (handling any errors) and then pass it into the control (JTable/JList) models.
But again, you are probably going to run into situations where you find yourself with a standard model (such as a table model) and you are reading you data from a separate model (such as resultset or such (only an example) - because performance is improved or what ever) where the model will be presented with the task of trying to deal with the exception.
In this case, I can only suggest you provide your models with some kind of error handler/listener that is capable of reporting the errors back to the UI. If you can, us an interface, this will allow you to decouple the view/models if you need to.
Just some ideas
Related
I'm trying to make a design based on the Uncle Bob's Clean Architecture in Android.
The problem:
I'd like to solve is how to make the changes generated in one repository to be reflected in other parts of the app, like other repositories or Views.
The example
I've designed a VERY simplified example for this example. Please notice that boundary interfaces has been removed to keep the diagrams small.
Imagine an app that shows a list of videos (with title, thumnail and like count), clicking a video you can see the detail (there you can like/dislike the video).
Additionally the app has an statistics system that counts the number of videos the user liked or disliked.
The main classes for this app could be:
For the Videos part/module:
For the Stats part/module:
The target
Now imagine you check your stats, then navigate the list of videos, open the detail of one, and click the like button.
After the like is sent to the server, there are several elements of the apps that should be aware of the change:
Of course the detail view, should be updated with the changes (this can be made through callbacks so no problem)
The list of videos should update the "likes" count for the given video
The StatsRepository may want to update/invalidate the caches after voting a new video
If the list of stats is visible (imagine a split screen) it should also show the updated stats (or at least receive the event for re-query the data)
The Question
What are the common patterns to solve this kind of communication?
Please make your answer as complete as you can, specifying where the events are generated, how they get propagated though the app, etc.
Note: Bounties will be given to complete answers
Publish / Subscribe
Typically, for n:m communication (n senders may send a message to m receivers, while all senders and receivers do not know each other) you'll use a publish/subscribe pattern.
There are lots of libraries implementing such a communication style, for Java there is for example an EventBus implementation in the Guava library.
For in-app communication these libraries are typically called EventBus or EventManager and send/receive events.
Domain Events
Suppose you now created an event VideoRatedEvent, which signals that a user has either liked or disliked a video.
These type of events are referred to as Domain Events. The event class is a simple POJO and might look like this:
class VideoRatedEvent {
/** The video that was rated */
public Video video;
/** The user that triggered this event */
public User user;
/** True if the user liked the video, false if the user disliked the video */
public boolean liked;
}
Dispatch events
Now each time your users like or dislike a video, you'll need to dispatch a VideoRatedEvent.
With Guava, you'll simply pass an instantiated event object to object to EventBus.post(myVideoRatedEvent).
Ideally the events are generated in your domain objects and are dispatched within the persisting transaction (see this blog post for details).
That means that as your domain model state is persisted, the events are dispatched.
Event Listeners
In your application, all components affected by an event can now listen to the domain events.
In your particular example, the VideoDetailView or StatsRepository might be event listeners for the VideoRatedEvent.
Of course, you will need to register those to the Guava EventBus with EventBus.register(Object).
This is my personal 5cents and maybe not closely enough related to your example of "The Clean Architecure".
I usually try to force a kind of MVC upon androids activities and fragments and use publish/subscribe for communication. As components I have model classes that handle business logic and the data state. They data changing methods are only to be called by the controller classes which usually is the activity class and also handles session state. I use fragments to manage different view parts of the application and views under those fragments (obviously). All fragments subscribe to one or more topics. I use my own simple DataDistributionService which handles different topics, takes messages from registered publishers and relays them to all subscribers. (partly influenced by the OMGs DDS but MUCH MUCH more primitive) A simple application would only have a single topic e.g. "Main".
Every part of view interaction (touches etc) is handled by its fragment first. The fragment can potentially change a few things without sending notifications. E.g. switching the subrange of rendered data elements if the rest of the app does not need to know/react. Otherwise the fragment publishes a ViewRequest(...) containing the necessary parameters to the DDS.
The DDS broadcasts that message and at some point reaches a controller. This can simply be the main activity or a specific controller instance. There should be only ONE controller so that the request is only handled once. The controller basically has a long list of request handling code. When a request arrives the controller calls to the business logic in the model. The controller also handles other view related things like arranging the view (tabs) or starting dialogs for user input (overwrite file?) and other things that the model is not supposed to know about but influences (Throw new NoOverWritePermissionException())
Once the model changes are done the controller decides if an update notification has to be send. (usually it does). That way the model classes do not need to listen or send messages and only take care of busines logic and consistent state. The update notification ist broadcasted and received by the fragments which then run "updateFromModel()".
Effects:
Commands are global. Any ViewRequest or other kind of request can be send from anywhere the DDS can be accessed. Fragments do not have to provide a listener class and no higher instance has to implement listeners for their instanced fragments. If a new fragment does not require new Requests it can be added without any change to controller classes.
Model classes do not need to know about the communication at all. It can be hard enough to keep consistent state and handle all the data management. No message handling or session state handling is necessary. However the model might not be proteced against malicous calls from the view. But that is a general problem and cannot really be prevented if the model has to give out references at some point. If your app is fine with a model that only passes copies/flat data its possible. But at some point the ArrayAdapter simply needs access to the bitmaps he is supposed to draw in the gridview. If you cannot afford copies, you always have the risk of "view makes a changing call to the model". Different battlefield...
Update calls might be too simple. If the update of a fragment is expensive (OpenGL fragment reloading textures...) you want to have more detailed update information. The controler COULD send a more detailed notification however it actually should not have to/be able to know what parts of the model exactly changed. Sending update notes from the model is ugly. Not only would the model have to implement messaging but it also gets very chaotic with mixed notifications. The controler can divide update notifications and others a bit by using topics. E.g. a specific topic for changes to your video resources. That way fragments can decide which topics they subscribe to. Other than that you want to have a model that can be queried for changed values. Timestamp etc. I have an app where the user draws shapes on canvas. They get rendered to bitmaps and are used as textures in an OpenGL view. I certainly don't want to reload textures everytime "updateFromModel()" is called in the GLViewFragment.
Dependency Rule:
Probably not respected all the time. If the controller handles a tab switch it can simply call "seletTab()" on a TabHost and therefore have a dependency to outer circles. You can turn it into a message but then it is still a logical dependency. If the controller part has to organize some elements of the view (show the image-editor-fragment-tab automatically after loading an image via the image-gallery-fragmen-tab) you cannot avoid dependencies completely. Maybe you can get it done by modelling viewstate and have your view parts organize themselves from viewstate.currentUseCase or smth like that. But if you need global control over the view of your app you will get problems with this dependency rule I'd say. What if you try to save some data and your model asks for overwrite permission? You need to create some kind of UI for that. Dependency again. You can send a message to the view and hope that a DialogFragment picks it up. If it exists in the extremely modular world described at your link.
Entities:
are the model classes in my approach. That is pretty close to the link you provided.
Use Cases:
I do not have those explicitly modelled for now. Atm I am working on editors for videogame assets. Drawing shapes in one fragment, applying shading values in another fragment, saving/loading in a galleryfragment, exporting to a texture atlas in another one ... stuff like that. I would add Use Cases as some kind of Request subset. Basically a Use Case as a set of rules which request in which order are allowed/required/expected/forbidden etc. I would build them like transactions so that a Use Case can keep progressing, can be finished, can be cancelled and maybe even rolled back. E.g. a Use Case would define the order of saving a fresh drawn image. Including posting a Dialog to ask for overwrite permission and roll back if permission is not give or time out is reached. But Use Cases are defined in many different ways. Some apps have a single Use Case for an hour of active user interaction, some apps have 50 Use Cases just to get money from an atm. ;)
Interface Adapters:
Here it gets a bit complicated. To me this seems to be extremely high level for android apps. It states "The Ring of Interface Adapters contains the whole MVC architecture of a GUI". I cannot really wrap my head around that. Maybe you are building far more complicated apps than I do.
Frameworks and Drivers:
Not sure what to think of this one. "The web is a detail, the database is a detail..." and the graphic contains "UI" in this Ring as well. Too much for my little head
Lets check the other "asserts"
Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
Hm yeah well, if you run your own architecture that is what you get.
Testable. The business rules can be tested without the UI, Database, Web Server, or any other external element.
As in my approach model classes neither know about controllers or views nor about the message passing. One can test state consistency with just those classes alone.
Independent of UI. The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
Again a bit overkill for android is it not? Independence yes. In my approach you can add or remove fragments as long as they do not require explicit handling somewhere higher up. But replacing a Web UI with a console UI and have the system run like before is a wet dream of architecture freaks. Some UI elements are integral part of the provided service. Of course i can easily swap the canvas drawing fragment for a console drawing fragment, or the classic photo fragment for a 'take picture with console' fragment but that does not mean the application still works. Technically its fine in my approach. If you implement an ascii console video player you can render the videos there and no other part of the app will necessarily care. However it COULD be that the set of requests that the controller supports does not align well with the new console UI or that a Use Case is not designed for the order in which a video needs to be accessed via a console interface. The view is not always the unimportant presenting slave that many architecture gurus like to see it as.
Independent of Database. You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
Yeah, so? How is that directly related to your architecture? Use the right adapters and abstraction and you can have that in a hello world app.
Independent of any external agency. In fact your business rules simply don’t know anything at all about the outside world.
Same here. If you want modularized independent code then write it. Hard to say anything specific about that.
I am writing an application where I am confused how to communicate between the business layer and service layer. Let me clear my point by giving example:
createStusdentRecord is method in service layer, I am calling this from business layer. now approach 1 : Create different custom exceptions and throw if some data is missing etc, and on success return studentid, let the business layer handle these exception.
Approach 2 : Create one class SMD ( status message and data ) and handle all exception in service layer. Return this SMD to business layer, with no exception handling in business layer.
Which approach is better and why?
What should be approach when we expose web-services?
I would go with Approach 1. Assuming these truly exceptional conditions that the caller can handle.
I like exceptions because then there is a way to find out why something failed. Hiding all errors or just returning a boolean for success/fail is a bad practice.
The point is to try to hide as much internal stuff as possible to hide implementation details as well as stuff the other layers don't know about (or want to know about) but balance that with enough information if there is a problem.
Student s = dao.createStudent(...)
If the given parameters are invalid do you throw an exception? Maybe depends why they are invalid. Perhaps it's a good idea to make custom Exceptions for concepts such as "A Student with these parameters already exists". However, something like "parameter is invalid" might be a better choice to use one of the JDK built in exceptions like "IllegalArgumentException".
Furthermore, I would make all your custom Exceptions subclass a parent "DaoException" so client code that only cares about success/fail catch catch the parent, but something that wants more fine grained control can always catch subclasses.
Should I have a bean for every form, datatable etc in JSF?
For example, I have a form for registration, which simply has 2 fields and a button which are:
nickname, password, submit
Should submitting this form go to a RegistirationFormBean or somewhere in UserBean or UserServiceBean?
What is the best practice?
Thank you.
To decide whether or not you should create a #ManagedBean exclusively for a component of the page (e.g. form, datatable), I believe you should think about the modularity of your design.
The 1st question you should ask yourself is: Will the component be re-used in many pages?. For example, on sensitive pages such as ChangePassword or DeleteAccount, usually, you will ask the user to enter the current password to validate his identity before performing any logic. In this case, you should definitely have an exclusive bean for the validating password component so that you can re-use the component again and again without having to re-code the validating function every time.
Secondly, I usually use #ManagedBean as a place to hold all the related functions that work toward the same goal. This grouping of functions can be pretty subjective. For example, I can have a page called CreateProduct.xhtml with a bean called CreateProductBean that has all the functions for creating a product. In this case, it's like 1 bean per view. Another way is to have a bean called ProductManager that has functions for everything related to the Product object (i.e. create, read, update, remove). In this case, it's like 1 bean for many views (e.g. CreateProduct.xhtml, RemoveProduct.xhtml). For ease of future maintenance and division of work, I usually use 1 bean per view. The 2nd approach 1 bean for many views is also good on certain situations but I suddenly cannot think of an example yet :P... I will update my answer when I got a good one ;).
Thirdly, I prefer to follow the 3-tier MVC model and separate back-end logic away from the front-end. For example, to persist a new account in the database, I will inject an #EJB or a #WebServiceRef to ask the back-end system to perform the necessary logic. It's definitely more maintenance friendly in the future :).
So, using your RegisterAccount example, I will have
1 bean called UserExistenceValidator to check if a nickname exists in the database. During registration, I can throw an error if the user chooses a nickname that is taken. I can also use this bean to check if a user exists in the AddFriend.xhtml page.
Another bean called RegistirationFormBean to capture a user's inputs and talk to the back-end to persist the new account.
Its actually a pretty interesting topic to tweak any JSF lover's brain, so I could not resist myself and I would like to go with detail explanation.
One of the very interesting and significant cause behind the invention of JSF was, wiring client side event to server side application code like any swing application and getting rid of handing of request and response object explicitly. Like any swing application, we can now simply bind any client side event (say, button click) with some server side code to handle that event, without worrying the facts and complexities of writing an web application.
As a result when designing any web apps, that uses JSF, the designer can focus on the user experience as easily as designing an event driven swing application. So as the consequence, you design the view pages and identify the events to do tasks and navigate between the views. Finally you write some server side codes to be executed in those events, to do the job you want. Those server side codes reside in your managed beans.
If we classify based on the type responsibility, there are several types of managed beans:
Model Managed-Bean
Backing Managed-Bean
Controller Managed-Bean
Support Managed-Bean
Utility Managed-Bean
You will find the details of each of the type in this article.
Your problem is, how to distribute the responsibilities of Controller Managed-Bean. There are several issues to consider, while you are distributing this kind of responsibilities:
The complexity of the task to do.
Re-usability of it.
Modularity in terms of responsibility (type of jobs to do).
Modularity in terms of business perspective.
Decoupling the responsibilities. etc.
You can design your system to with a single controller for all the views of your simple CURD operations of a model. But if you need to handle multiple complex transactions in your single create operation, then separating the operations to multiple controllers, would be a better design. Though your registration procedure is pretty much simple, you should use a separate controller to handle the task. Because it will not be a good idea, to put any task in the same managed bean, that is not simple and related enough to reside with the task "registration". I think this, concludes your query!
you should a data transfer object bean and a domain bean for ui submission and for persistence in db respectively.
using a controller class, process your ui jsf submission data and create a clean domain bean and use this to persist.
the best practice should always de-couple processes/entities if possible.
also your dto bean might have accessory and more data than your domain bean which u might require for several purposes.
In similar situations, I always have a UserManagedBean that handles user relative operations, such as login, registration, change password, etc...
To deal with these operations, I put an attribute in the UserManagedBean of type User (or whatever class name) which corresponds to the persisted data related to users (usually in DB table user).
In your case nickname and password are attributes of the User class. As for the submit it will invoke a method in the UserManagedBean to authenticate user:
<h:inputText value="#{userManagedBean.user.nickname}"/>
<h:inputSecret value="#{userManagedBean.user.password}"/>
<h:commandButton value="Login" action="#{userManagedBean.loginUser}"/>
Of course, the loginUser method will invoke a call to the service layer which will invoke DAO layer to check credentials against DB (or other storage).
If the login is successful, the user attribute in our managed bean (which should be session scoped) is initialized with returned object from DB.
As described here, I want to update the user's database by means of catching the exception that occurs when the entity classes don't match. I understand that I could add a catch statement to every db-interface method, but that's error-prone*. Other 'polling methods' are also possible, but they are not interrupt-driven as I want through catching exceptions.
I think what I'm looking for is to catch the exception before it's delivered to the user (possibly to crash the application). I would put there my catch block. I'd have put it in the main() in a non NB app.
My understanding is that the exception is thrown on an entity basis (i.e. a method that involves only one entity, which has not changed, will not throw any exceptions, although other entities have changed).
I had a similar problem, but I guess mine is a bit harder to solve. I use JPA at server side, and the server is actually a webservice provider.
The persistence is managed by the container, and according to my app settings, it uses a "Create" strategy. Of course, every time I change my entities and redeploy the application it throws a lot of exceptions.
What I finally decided to do is to create/migrate the existing database in a separate process. This is, reading the metadata associated to the entities and comparing it with the current database.
Afterwards, it creates a migration script in case the db schema is different to fit it into the new one without losing any information (the migration script generation complexity depends on how do you plan to handle cases like data type changes or attribute removal). The last step is redeploying the app (in your case start it).
I'd suggest a proactive approach, where you don't wait for the exception to be thrown, but trying to guess the changes before to run the application.
I am developing a medium size Java Web Application with Struts as MVC framework and simple JDBC at Data Access Layer. I have been searching for exception handling best practices in such an application. I have found several articles, some of them being contradictory, only making me more confused rather than making things clear and simple. Some say it is better to reuse existing exceptions instead of defining application specific exceptions, others present a huge hierarchy of application specific exceptions for every minor trouble that may occur in the system. Some say it is better not to handle exceptions at Data Access Layer and delegate them to the Service Layer, others say Data Access Layer exceptions should be caught locally since delegating them to Service Layer would violate the abstraction between the two layers. And so on.
I would highly appreciate if you let me know of links/names to articles/books that present solid solutions which have worked for you in such a scenario. The solution should clear at least the following points with justifications:
Where the SQLExceptions be caught?
Where exceptions should be logged?
Should unchecked exceptions be logged?
Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
How checked exceptions be handled, which of them to be shown to the user and how?
How should a global exception handler page be used?
How should struts ActionErrors be used in this context?
Thanks
1: Where the SQLExceptions be caught?
In DAO classes in data access layer. You can if necessary wrap it with a custom DAO exception. This DAO exception in turn needs to be handled further as checked exception.
2: Where exceptions should be logged?
At the moment when you're about to throw them or to pass through the messaging framework.
3: Should unchecked exceptions be logged?
They should certainly be logged. They should namely not occur in real world, because those are sign of a fault in the code logic (i.e. developer fault) which needs to be bugfixed asap. They should be thrown all the way up to the container and let the container handle them with an <error-page> in web.xml. To log (and eventually mail) them, use a Filter which listens on the error page.
4: Should unchecked exceptions be caught at presentation layer, and should they be shown to the user?
They should not occur at all.
5: How checked exceptions be handled, which of them to be shown to the user and how?
If they are result of errorneous user input (e.g. not a number, bad email, constraint violation, etc), show them in the same form to the user. Otherwise (e.g. DB down, DAO exception and so on) either throw it all the way up to the error page, or display the error with a message to try again later.
6: How should a global exception handler page be used?
At least in an user-friendly manner. Thus, in the same layout, with some introductory "sorry" and if necessary with some error details and an email address so that the user can contact for the case that.
7: How should struts ActionErrors be used in this context?
Show them in same form to the user.
If you can't recover from an exception, then you should let it flow out of your code (often by making it unchecked, or wrapping it in an unchecked exception). If they remain checked, you have to cater for them at each level of your code, and consequently at every abstraction layer. SQLExceptions would normally fall into this category (you'll have to wrap them since they're checked).
For these exceptions, I normally log at the highest level, but present a page to the users simply detailing that something has gone wrong. Normally my users aren't interested in stack traces. But I usually offer them a page to let them describe what they were doing at the time, and the logged exception ties back to this submission via a unique id (recorded in the form and in the log file with the exception). That allows me to tie back users' actions to the resulting exception.
The above assumes that you can't recover from SQLExceptions, and if the database is down, then you can't do something meaningful. There are exceptions to this, of course. You may find that you're talking to multiple systems, and one being down doesn't mean you can't continue in some fashion (e.g. the Amazon home page reportedly relies on 100 services, and needs to run regardless of some of these being down).
I would expect declared exceptions to be at the same level of abstraction as the interface/methods defining them. e.g. a TradeStore would be declared to throw a TradeException, not a SQLException (since methods of storing a trade are an implementation of TradeStore - you could store in a relational db, a JavaSpace etc.).
As a warning, when displaying lower level error messages to users, make sure they're sanitized of system information. This is an area where many security exploits originate. Log them with full information, but only display a more general error message to the user.