Model Instances
When writing applications you usually have the model, the business logic and some kind of views for the user to interact with your application. So you have the venerable MVC pattern and everything is perfect.
You have your model that can be accessed by the views to be displayed. You have the controller that manages the views and dispatches/delegates business logic.
But that is just too abstract. Everything looks fine when it is abstract. You first encounter the problem when you face the details.
One of these “problems” is as simple as the instantiation of the model’s object. Not the instantiation per se but WHERE the instances are created.
I will explain myself further with the following example.
Suppose you write an online store application in Java. You will probably use JSF/Struts for the View and JPA/Hibernate for the model. In the business layer there are much more options depending on the size and/or requirements of the application. But let’s say we use EJB 3.0
As you may guess, you have a class Product which misteriously represents a… product.
So, where do you create an instance of the class product? In the view? the view being a managed bean in JSF. Through a EJB? Or you have a centralized way to do that, like a Factory.
Let’s explore the three options a little bit.
Instantiation in the View
Yes, you don’t need nothing but a simple call like: “new Product();” in order to create a new Product. You first need and instance of it, so that you can later populate it with data. So it seems it makes sense to just create the instance in the managed bean, populate it with data using some binding and then just give the instance to an EJB in order to save it.
To be honest, although it is very straightforward, I don’t feel well about it. I feel as if I were violating some indisputable principle here. So, the other possible solution would be:
Let’s the business logic create the model
That is, an EJB creates the instance and returns it to the view. Like a kind of pimped factory and it just fits very well if you need some business logic to create an instance of a Product. Mmmh, but then I think, a call to an EJB just to create a simple and plain instance? Ok, may be it is not too bad, since both the Managed bean and the EJB are on the same server. But what if later on we decide to write a remote client?
A factory could do that
So we arrive at the conclusion that a normal factory, without the EJB stuff, would suffice. But then you have may be 15 or 20 objects that represent your model. The factory would be kind of big to say the less.
What about a sophisticated over-engineered solution like DI to create and assign a simple instance? Not that DI is an over-engineered solution, but you would have to wire everything up in order to assign the instance of the model to the instance of your managed bean.
At the end, I think the answer is the typical: it depends! It depends on how big your application will be. If the application will grow into a clustered environment or if your application is just a simple web app that requires some EJB-stuff (like transaction management).
Anyway, I am a little bit wary about the direct instantiation in the view related objects. I don’t know. I just have a bad feeling about it. Like you know it is wrong, but you do it anyway. The main problem with this is that you, more often than not, do not know how big the application will be. If you do the instantiation in the view and your application grows and it grows fast, then you will have a mess there with instance everywhere and it will be difficult to change the implementation of one of the model’s classes without doing a lot of refactoring. Although, you normally wont’ change the implementation of a domain object. Unitl now I have never done that in any of my projects. By changing the implementation I mean replacing the class with a new one.
So you see, it is not as easy as one could think. We are now living an era of converting anti-patterns into patterns and viceversa.
Anyway I think a centralized factory would be good from the beginning for a mid-size project. It could also help when testing the app. You should must avoid EJBs as a factories otherwise you will be locked to one technology. What happens if you must use Spring instead of EJB later as a requirement? Well, what it will happen is, that you will have to refactor your app in every place you get a new instance of the model.
If you still require an EJB to instantiate an object (may be you need more information to create an instance and this information must be fetched from the database which are normally accessed by an EJB through the EntityManager) then retrieve first all the information you need through the EJB and then pass that information to the factory.
Ah and believe me, I have seen the four scenarios described above and the worst of all is that they were used in the wrong way.