I have a form which collects user input. Then a servlet collects all the request parameters and stores it to the database. As per MVC I should have passed it to a bean and the bean should have updated the database. Is it bad programming?
Also I have to parameters "title" and "source URL". I want the title to embed the source URL.
The JSP is your view, and the Servlet is your controller.
To have full MVC, there should be another Java class who's job is simply to represent the objects being stored; that's the model. Or it may be more than one class, if the form takes multiple objects, depending on your data model.
If you're writing SQL directly into a Servlet, that's not great code; any changes you ever make to your database will require a painful update to many of your Servlets. The idea of pulling the data model code away into another class lets you make changes to the data and database without having to edit everything you write.
So, if you're writing a really simple app, this is likely fine. If you're writing something complex, this is fine for a prototype, but you'll want a stricter MVC implementation if it's something you'll have to build, maintain, and own for any length of time.
Related
I'm building a Java web app that follows the MVC model.
I have a number of JSP pages that act as views for the respective objects in the DB, for example product_details.jsp.
I plan to use URLs like product_details.jsp?id=123, and since I have quite a lot of View pages, I was wondering if it was necessary to write a servlet for each of them that only retrieves data from a DAO or if there was a clean way to call a DAO from inside the JSP itself.
Would this violate the MVC model even if no controller is needed? What would be the best approach?
I'm working on a school project and or task is to design a project management tool. We are allowed to use any design pattern as long as we can explain how it's good according to the GRASP principles.
I'll give a synopsis of the project tool:
CRUD-functionality for projects
CRUD-functionality for tasks (a project has tasks)
CRUD-functionality for users (a user is assigned to tasks)
A simple GUI
We decided to go with the MVC-pattern and we are not allowed to use a database. My question is: Where should I store objects?
Should I do this in the controller? Currently we do it like this:
public class ProjectController
{
private ArrayList<Project> projects;
public ProjectController(TaskController taskController)
{
projects = new ArrayList<Project>();
}
}
I have a feeling there is something wrong with keeping the objects in the controller but I can't explain why. Anyone that can explain what's the best practice according to the GRASP-principles?
EDIT:
Thank you, learned from everyone something but can only pick one answer.
For a very short answer : NO, don't put your store in the controller. This is a bad idea and it goes against the MVC principle.
Usually, the model is the only place responsible for your data BUT it is frequent that the M part is split into :
Fetching the data.
Storing the data in the application.
The interesting part in this is that, no one cares where your data come from. A database, a file, an API rest. whatever, it doesn't matter.
I'm not saying i have the best solution for you but here is how you could do this with an example.
You store your user data into a file.
You create a php class UserDataRepository that fetches the user data files, and sets the data into your UserModel class.
From the controller, you call your UserDataReposiroty and get back your UserModel.
This way your controller doesn't have any idea how you are fetching the data. He just asks a repository to fetch them and it returns the UserModel that the controller is allowed to manipulate.
I hope this will help you
Increase abstraction.. Create a model class. Create your arraylist (model objects) there. Your controller should still access/call model methods.
Tomorrow, you might want to dump that data into a file or into a DB, you will have one hell of a ride doing that with the current design. So separate your model from your controller and keep the design clean.
No. If you store data in the controller then you are not using MVC. You have to do it in the Model. You can store in memory or files, but always store data throw the model. For example, you could implement DAO pattern to manipulate data.
Maybe, not now, but then you will need a database. With DAO pattern, it won't be difficult to adapt your current persistence kind to a database.
In MVC pattern, M means models, V means view, C means controller. A common MVC application progress is that once a request is coming, controller get it and do necessary processing, retrieving results data, then pass the results data to view for rendering. After view layer is rendered, it displays to users via GUI.
So controller can be regarded as a commander, it controls process, but it is not good to handle data retrieving in controller. Model should be responsible for retrieving and organizing data. That means data objects should be stored in Model instead of Controller, Controller calls Model to retrieve data objects. Take Java application as example, usually these parts are needed:
ProjectController, it calls ProjectService.getAllProjects() method to retrieve result. Once retrieved, view layer use the result to render GUI for display. I suggest Controller layer should be thin.
ProjectService, it has method getAllProjects(), this method calls ProjectDAO.getAllProjects() method to retrieve projects data, and maybe other handling. Here business logic goes.
ProjectDAO, it has several methods which deal with Project objects, deal with data in this layer! But these methods should be independent with business logic(as business logic should be deal in ProjectService).
Project object.
Hope it helps.
I have been working both on spring and grails (grails is built on spring).
We can pass our data from controller to view (jsp/gsp) via request object or via model.
Passing data via model is preferred because its easy.
Comparison of code :
Spring :
controller request.setAttribute("name","india");
view ${pageContext.request.getAttribute('name')}
controller ModelAndView("viewname",modelObject)
Grails
controller request.setAttribute("name","india")
view ${request.getAttribute("name")}
controller render(view:"viewName",model:[name:"india"])
I think request object does many functionalities other than this.
So my question is : If passing data from controller to view can be done with request object itself why java technology required to make a concept like model ?
necessity is mother of invention
I mean to say that there must be a task that can be implemented only via a model.
A few things come to mind, but they are speculation as to why.
Mainly, separation of concerns. Modifying the request, which is input, to hold output seems to be abusing this. The model is clearly ouput, and only output.
By clearly defining what constitutes output, using a model, frameworks such as Spring and Grails can then apply other processes to only the model. Grails filters come to mind, as an example.
That's my quick opinion.
That data which a controller gathers up and needs to make available to the view should be put in the model. That is kind of the definition of what the model is in this context. Never use request attributes for this.
I've been told that MVC is an architecture pattern for the presentation tier on a multi-tier architecture. I didn't understand the MVC Model concept.
So I made a web application, as an aproach to learn MVC model, only using JSP and Servlets, I made the DataAccess layer too.
In my WebContent folder, I put all the views.
In my src (Java content) folder, I made 4 packages.
data
presentation.model
presentation.controller
businessEntities
I used Servlets as Controllers (used the FrontController pattern) and JSP for all the Views.
As the title says, my problem is with the model.
Now, lets make an example..
I have 2 classes.
- Car
- CarLogic
CarLogic is a class that calls a possible CarDAO to get data and to return it to anyone who asks it. Car is just the POJO.
I placed CarLogic inside presentation.model and Car on businessEntities.
Am i wrong? What should i put on Model package?
Thanks!
When nested in the presentation layer of a multi-tier architecture, MVC's models are usually nothing more than (possibly enhanced) key-value maps.
The controller, after having called the appropriate business layer service, instanciate a new map with the values the view will have to display.
Spring MVC for example implemented the MVC pattern this way: see how the ModelMap extends LinkedHashMap.
See this answer to see a typical HTTP request life cycle, when the MVC pattern is nested in the presentation layer of a 3-tier architecture.
So to sum up, I would put CarLogic in your businessEntities package, and the Car POJO
within a new presentation.bean package for example (so you won't need your presentation.model package anymore). Thus, your controller would add the Car instance as an attribute of the request, which would then play the part of the model:
request.setAttribute("theBean", yourBeanInstance);
In your JSP views, simply use ${theBean.anyProperty} to access the attribute (don't forget the getter in your bean). Note that the EL will scan the following scopes in given order: page, request, session, application; the first found match will then be returned.
Model View Controller in and of itself is a pretty simple pattern.
From the wikipedia artical:
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its associated view to change the view's presentation of the model (e.g., by scrolling through a document).
A model notifies its associated views and controllers when there has been a change in its state. This notification allows the views to produce updated output, and the controllers to change the available set of commands. In some cases an MVC implementation might instead be "passive," so that other components must poll the model for updates rather than being notified.
A view requests information from the model that it needs for generating an output representation to the user
At least it was simple pre-web and pre-SOA.
The view part is still pretty straight forward, it simply presents the model.
Controller-wise, the web, in its traditional http/html sense rather than the newer JavaScript/AJAX/websocket sense, has made the controllers iteraction with the view much more visible than it was in say a Swing application. This means in addition to their traditional role, controllers in a web-app are likely to not only interact with the model but also have some knowledge of the views.
Model-wise, pre-SOA the model represented both the data and the behaviour of the business. More recently anemic domain models have become popular with behaviour implemented in separate classes from the representation of the data, which is passed to the logic classes (services).
It's this point, relating to the separation of data and logic that I believe your question relates to. Personally, for simple systems, I prefer a rich model with the data and behaviour in the same classes, hence the packaging is simple. However I appreciate that sometimes the benefits in separating the logic from the data and in such cases I'd create a separate package (and probably a separate jar) to contain that logic.
The word "model" means subtly different things in the term "model-view-controller", and when you say "model layer" in an n-tier architecture such as yours. From the point of view of MVC, everything the controller passes input to, and fetches viewable data from, is the "model".
This includes your domain model (Car), and business logic (CarLogic). You don't need to necessarily structure your application to exactly match the pattern you're using on the UI side. (In fact, the MVC pattern is probably insufficient to cover an entire application to begin with.)
So in your case, putting Car into businessEntities is fine. Not sure about having presentation.model to begin with – business logic isn't a presentation concern, and probably belongs in a layer on its own. Which is where I'd put CarLogic.
I have no idea what the data package is supposed to be at all.
This split means there doesn't seem to be a dedicated presentation model in your application. This might or might not be an issue. In a web application, what the presentation model usually does is encapsulate user input, or maps the business entities to a structure that fits the needs of the view better – flattening complex relationships etc. (In classical Spring MVC, these would be the Command and Model classes.) In a simple enough application, or using an advanced enough web framework, it's possible to directly use domain model entities in your views.
As an example of what a distinct presentation model would do, consider the internal system a school would use. You'd have a bunch of students, and some classes they can enroll in. At the business entity layer, you'd probably have a separate Enrollment entity that would hold attributes like date of enrollment, references to the grades a student got in the class, etc. However, when a view in the application needs to display the list of classes a student is enrolled in, it doesn't really need to see the Enrollment object at all. Thus it makes sense to have a presentation model object Student that only has a list of Class objects in it. (And the requisite code that reads the business entities and maps them correctly to this structure.)
From Wikipedia about MVC:
Model–view–controller (MVC) is a software pattern for implementing user interfaces. It divides a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user. The central component, the model, consists of application data, business rules, logic, and functions. A view can be any output representation of information, such as a chart or a diagram. Multiple views of the same information are possible, such as a bar chart for management and a tabular view for accountants. The third part, the controller, accepts input and converts it to commands for the model or view.
I highlighted one sentence, that usually is not understood. The model is a really rich model. That means, it also contains every logic that works with the data. It is up to you, whether to have separate classes for data and for logic (which reduces the data classes to structs or records), or whether to have richer data classes that already contain some business methods (the way that I prefer).
That said, the controller is just the interaction between the model and the view. In Swing applications - for example - the controller is nothing else than the various listeners (an ActionListener, for example).
So, to answer your question: Having a separate data access layer is a good thing. This is where your DAO class belongs to. The data and logic classes (the model) belongs to the model package. I would not create several packages for them.
MVC is a common design pattern used by many modern web frameworks, f.e. GRAILS, Spring MVC or ASP.NET MVC. You see the MVC pattern is included in their names ;)
For the MVC-pattern you actually need three packages:
model
controller
view
In the model package you put your classes which will be used to hold your data. The controller classes contains the logic to controll which view is called and which data should be used in those views. The views itselfs contains the information how to display your data on the screen. There shouldn't be any great logic, f.e. just JavaScript. The business logic should contained in a separate package. If you need this logic, you can call is from your controller.
Your packages are (I hope i read them correctly!):
data
presentation.model
presentation.controller
businessEntities
According to the MVC-pattern is suggest the following usage of your packages:
"data" or "model" - use this for your Car class
"controller" - use this for your controller logic
"presentation" or "views" - use this for your views to display your data on the screen
"businessLogic" - use this for your CarLogic class
MVC stands for Model View Controller.
Model is where you store entity objects
View you store Presentation objects
Controller is where you map your attributes that are present in the Model to the widgets.
so that the attributes are set to the entity objects from the widgets input.
In my Spring MVC application I am using DTO in the presentation layer in order to encapsulate the domain model in the service layer. The DTO's are being used as the spring form backing objects.
hence my services look something like this:
userService.storeUser(NewUserRequestDTO req);
The service layer will translate DTO -> Domain object and do the rest of the work.
Now my problem is that when I want to retrieve a DTO from the service to perform say an Update or Display I can't seem to find a better way to do it then to have multiple methods for the lookup that return different DTO's like...
EditUserRequestDTO userService.loadUserForEdit(int id);
DisplayUserDTO userService.loadUserForDisplay(int id);
but something does not feel right about this approach. Perhaps the service should not return things like EditUserRequestDTO and the controller should be responsible of assembling a requestDTO from a dedicated form object and vice versa.
The reason do have separate DTO's is that DisplayUserDTO is strongly typed to be read only and also there are many properties of user that are entities from a lookup table in the db (like city and state) so the DisplayUserDTO would have the string description of the properties while the EditUserRequestDTO will have the id's that will back the select drop down lists in the forms.
What do you think?
thanks
I like the stripped down display objects. It's more efficient than building the whole domain object just to display a few fields of it. I have used a similar pattern with one difference. Instead of using an edit version of a DTO, I just used the domain object in the view. It significantly reduced the work of copying data back and forth between objects. I haven't decided if I want to do that now, since I'm using the annotations for JPA and the Bean Validation Framework and mixing the annotations looks messy. But I'm not fond of using DTOs for the sole purpose of keeping domain objects out of the MVC layer. It seems like a lot of work for not much benefit. Also, it might be useful to read Fowler's take on anemic objects. It may not apply exactly, but it's worth thinking about.
1st Edit: reply to below comment.
Yes, I like to use the actual domain objects for all the pages that operate on a single object at a time: edit, view, create, etc.
You said you are taking an existing object and copying the fields you need into a DTO and then passing the DTO as part of the model to your templating engine for a view page (or vice-versa for a create). What does that buy you? The ref to the DTO doesn't weigh any less than the ref to the full domain object, and you have all the extra attribute copying to do. There's no rule that says your templating engine has to use every method on your object.
I would use a small partial domain object if it improves efficiency (no relationship graphs to build), especially for the results of a search. But if the object already exists don't worry about how big or complex it is when you are sticking it in the model to render a page. It doesn't move the object around in memory. It doesn't cause the templating engine stress. It just accesses the methods it needs and ignores the rest.
2nd edit:
Good point. There are situations where you would want a limited set of properties available to the view (ie. different front-end and back-end developers). I should read more carefully before replying. If I were going to do what you want I would probably put separate methods on User (or whatever class) of the form forEdit() and forDisplay(). That way you could just get User from the service layer and tell User to give you the use limited copies of itself. I think maybe that's what I was reaching for with the anemic objects comment.
You should use a DTO and never an ORM in the MVC layer! There are a number of really good questions already asked on this, such as the following: Why should I isolate my domain entities from my presentation layer?
But to add to that question, you should separate them to help prevent the ORM being bound on a post as the potential is there for someone to add an extra field and cause all kinds of mayhem requiring unnecessary extra validation.