I am developing for learning purposes my very first "big" Spring MVC project. I am learning everything by myself (and of course, thanks to this amazing community).
What I am starting to wonder is... Is my design "correct/valid"? So far I am creating one Controller per View/Page specially because of the ModelAttributes (attached to the method).
Is that fine? Should I start doing it in some other way? Are there "offical" patterns in this matter?
To start, I assume you are creating a web project based on your use of ModelAttribute. You want to follow the MVC (Model, View, Controller) convention. The "Model" is the data you are manipulating. This data should be retrieved via a service layer. Then, your controller should call your service methods to get the data, making your controllers completely agnostic of your data. This is nice because you are free to change your data structure, e.g. migrating from MySQL to MongoDB, without worrying about changing your controller, all you need to change is your service layer. Also, this allows for controllers to use many different services in certain instances. Your controller receives requests from the client, e.g. the website user's page requests, GET/POST requests, etc., and performs some action, usually fetching/updating data via the service layer, and then returns a view. Each controller can take many requests, and can render many views. It is good practice to break up controllers by function. For example, if you had two different sections for your website, one for Admins, and one for Guests, then you may want to use one controller to process the Admin requests, and another to process the Guest requests. Each of these controllers can handle all requests from Admins/Guests accordingly. You may be a bit confused about controllers. Each method in a controller is bound to a single request/view, but a controller may have many such methods.
As you are learning, I would suggest exploring some client-side mvc frameworks like AngularJS. Angular allows very easy data binding and manipulation options, and makes it pretty easy to create RESTful web services.
Related
I want to build a Laravel application which users both web and API parts. The common (and mine as well) question is whether to use separate controllers or not.
There are 2 options:
Separate controllers
Laravel API controller structure?
Use one controller and check the request type (is Ajax, or depending on the request link) and return either JSON or HTML.
Laravel resource controllers for both API and non-API use
Those who have the 1-st opinion doesn't explain the DRY problem solution - web and API controllers would be the same except the return statement (JSON or HTML view). But since most post recommend to separate controllers I suspect I don't understand something about the DRY problem solution.
I don't see any disadvantage of the second method. But people say something like
If you use only one controller, you will end up soon with a messy class with thousands of lines. Not only this is not going to scale well, but it will be hard to work with for you and your teammates.
Please explain me the DRY problem solution for the first approach (separate controllers) and the possible underwater rocks in the second approach (single controller)
Please explain which approach is preferable.
I think this is a great question, and I too am keen to see the responses.
I can see the arguments for both approaches. I however would create and maintain separate controllers, whilst using services to share common logic between the controllers where it is known that this will never change.
For example, if you allow users to upload avatar images. I would put such logic in a service and consume this service in both controllers.
The reason for this approach in my mind, is that the web and API logic may diverge and it would therefore be easier to iterate each without impacting the other.
If this is unlikely, then I would still create separate routes, but point them both at the same controllers, so that if it did change in the future, you can simply re-point the API routes to their own controllers.
I'm creating a web app using an MVC framework. I thought of adding a layer between the controller and the domain models, I think it's called application layer in DDD, to avoid putting logic that is specific to a certain use case in the domain models.
The controller will only interact with this layer and this layer will orchestrate the operation using the domain models. This layer will be kept as thin as possible pushing all the logic that is not use case specific to the domain model.
I will call the classes that belong to this layer DomainCtrl.
Example login scenario:
Model: LoginForm
DomainCtrl: AuthCtrl
UI: ui controller
1.ui controller receives request
2.creates instance of AuthCtrl
3.AuthCtrl creates instance of a LoginForm and fill it with request data passed to authCtrl
4.LoginForm performs the login
5.authCtrl does other things that are specific to this specific way of login -> returns errors to ui controller
Is this a good way to organize an app?
Your question
Is this a good way to structure an app
is a very loaded question. The simple answer is Yes, but the more correct answer is It depends.
Let's start with the simple answer. Having your main application be unaware of the UI is generally a good idea. It means that you can easily consume your application from various places. In DDD this outer layer is usually called Application Layer. It is mainly responsible for orchestrating interactions between your domain, persistence and other resources that you might rely on. This also allows you to have your domain at the center unaware of everything else. This makes your domain easily testable and maintainable if implemented well.
Now the "it depends" part of the answer. DDD is not the only successful way to build an application, and in some cases it might be more of a hinderance than anything else. You have to ask yourself what is my app doing. Are there many domain specific rules? Am I only fetching and storing basic data etc? These are all questions you need to answer before you choose an architecture and technologies.
I would still say you probably won't go wrong by choosing the DDD approach as it is generally a good way to do things.
*Note: Your example is not that clear to me but you should be careful of spilling UI concepts into your domain/application. A login form is completely a UI concept as is auth to a certain extent. You can probably have your application return the details of your user, but the UI layer should decide if the user is allowed to proceed or not.
At a high level view, Yes
But it ultimately depends on "how" you logically separate your layers. In your scenario, I don't see any application layer.
I assume AuthCtrl is the domain? Who creates AuthCtrl? what layer does it exists?
To my understanding, MVC is a way to implement the separation of presentation tier from business and data tier. Am I understanding this correctly? If so, MVC should separate the business logic completely from presentation, right?
So to me it seems like javascript (or jquery) is somehow violating the MVC design since it takes over some of the logic on the client side, isn't it? Is model = data tier, controller = business tier, view = presentation tier? I think I have misunderstood the whole concept.
You seem to have a decent understanding of MVC. The trouble is that you are looking at two different potential MVC structures as one and the same. On the server, you can have data models, controllers, and views. On the client side, you can ALSO have data models, controllers, and views. If you want to look at your client side JavaScript as MVC, then jQuery is simply a utility that the view controllers can use to manipulate the view (the DOM).
Simply put, the client side doesn't always have to be only the view. If you use a web application client-side framework like Backbone, for example, then you can have models, views, and controllers all on the client side, which communicate with another, SEPARATE MVC structure on your server.
What you describe does actually pose a challenge for a lot of implementations. Frameworks such as the ASP.NET MVC Framework have been making attempts to auto-render JavaScript to the UI based on business logic in the middle tier (validation rules for form fields, primarily). But they're a long way off from having a truly compelling JavaScript user experience which doesn't repeat logic.
Personally, I like to think of the JavaScript as purely a UI concern. The application internally handles all of the logic. The JavaScript, as part of the UI, may duplicate some of that logic... but only for strictly UI purposes. Remember that the application should regress gracefully into a still-working state if the user has JavaScript disabled. That is, it should still use server-side (middle-tier) code to get the job done. All the JavaScript did was add a richer user experience to the UI layer.
JavaScript isn't the only culprit for this, either. Suppose you have a lot of validation logic in your middle tier defining what's valid or invalid for your objects. When you persist those objects to a database (which is on the periphery of the application just like the UI is), doesn't that database also contain duplicate validation logic? Non-nullable fields and such.
Congratulations! Your understanding of MVC is completely wrong. It has nothing to do with n-tier architecture (which is what you seem to be confusing it with).
The core idea of MVC is separation of concerns. This is used by dividing the application it two major layers:
model layer: contains all of the domain business logic and rules.
presentation layer: deals it user interface
The presentation then is further split into controllers (for handling the user input) and views (for dealing with response).
When applied to web applications, you either have MVC (or MVC-like) structure only on server-side, or, for larger and more complicated applications, you have separate MVC triads for both frontend and backend.
Also, when working with applications, the user of MVC is not human being, but the browser.
In latter case the backend acts like one data source for frontend application. An the whole frontend part of MVC is written in javascript.
P.S. In case if you are able to read PHP code, you can find a quite simple explanation of model layer in this answer. And, yes. It is the "simple version" because MVC is a pattern for enforcing a structure in large application, not for making a guesbook.
You can go to http://www.asp.net/mvc site and refer tutorials / samples to learn about MVC using Microsoft technologies.
I'm from a non-computing background and I'm struggling to getting my head around MVC design approaches and frameworks in general. I "get" code re-use, and separation of logic from display, and I "get" encapsulation and decoupling, but I don't get this.
At the moment I simply put everything in root, a separate subfolders for images, cfcs, and _includes, all database interaction via cfcs. I do all my processing at the top of the page, then a comment line then display/page layout below that.
Most of the frameworks I have looked at seem to favour a front controller, so my simplistic version of a top controller MVC design would be a subfolder for cfcs, controllers, and views and a big switch statement in index.cfm
<cfif not IsDefined("URL.event")>
<cflocation url="index.cfm?event=home" addtoken="No">
</cfif>
<cfswitch expression="#url.event#">
<cfcase value="home">
<cfinclude template="controllers/home.cfm"/>
<cfinclude template="views/home.cfm"/>
</cfcase>
<cfcase value="about">
<cfinclude template="controllers/about.cfm"/>
<cfinclude template="views/about.cfm"/>
</cfcase>
</cfswitch>
.. but what real advantage does that give me over a page controller design? Unless it's just the kind of sites I write, I always seem to find that the controller logic is specific to a view, its not like one controller could fit several views or several controllers could output to one view, so what would be the point of separating them?
The light hasn't come on for me yet, any pointers?
By "top" controller, I think you mean "front" controller, a single point of entry for requests into an application. As #bpanulla wrote, most ColdFusion frameworks use this design pattern. This becomes particularly interesting with URL rewriting, where it becomes easy to have search engine safe URLs by intercepting the a URL (e.g. domain.ext/i/am/friendly.ext) and routing it to some standard file such as index.cfm while making the requested URL a parameter (often as a request header). This also makes site redesigns where URLs change easier because it lends itself well to aliasing or redirects.
As far as controllers are concerned, they are usually tightly coupled to a particular URL or URL pattern. It's possible be more loosely coupled with controllers, but in practice I find that's an emergent property after multiple refactorings. What should be underlying the controller is one or more calls to a service layer that talks to the database, executes business process, creates stateful entities, etc... Then the controller receives the service layer's outputs and places them into whatever mechanism (e.g. an event object) is used to pass data to the view(s).
It's the service layer that's meant to be reusuable not the controllers. The controllers are merely an extension of whatever framework an application works within. The idea being that you should be able to switch frameworks with very little impact to the views and service layer. The piece that needs to be touched are the controllers.
So a given service object in a service layer should be able to service multiple controllers. For example, consider showing a logged in users' information as a widget on a site. There might be different pages served by different controllers, but each would call the same service object to get logged in user data that presumably might be given to the same view that renders the widget.
Update: Front Controller Advantages
Security: centralized authentication and authorization.
i18n & l10n: inject the right language pack into the request globally
Process Orchestration: think multi step checkout process for a shopping cart where you don't want the back and forward buttons to work - by routing everything through the front controller you're able to enforce what step (i.e. the state)
Logging & Tracking: easily add Google Analytics or other request tracking to a site by making the addition in just one place
Error Handling: centralized behavior
Now many of these items can also be done using <cferror> and Appplication.cfc, but I find it easier to have one centralized point.
Useful Links
http://java.sun.com/blueprints/corej2eepatterns/Patterns/FrontController.html
http://msdn.microsoft.com/en-us/library/ff648617.aspx
You actually implemented the crux of Fusebox (http://www.fusebox.org/) with what you wrote. There's nothing wrong with that, and most of the ColdFusion community used something similar to that for many years - Fusebox was the most-used CF framework (in my experience) until just a few years ago when ModelGlue, Mach-II and the other second generation CF frameworks came about.
One thing I can point out is that your approach to controllers (as .cfm files) actually does not enforce encapsulation in the typical OOD fashion, with specific arguments going to an object method call. Unless you are extremely dilligent, over time your .cfm controllers may wind up accumulated a large number of undocumented parameters that alter behavior to solve one problem or another.
With the various frameworks you also get nice features like Application, Session, and Request specific code (onApplicationStart, onRequestEnd, etc). But you can always get those through a simple Application.cfc.
When you start a new web application, which pattern are you choosing between MVC and MVP and why?
(This answer is specific to web applications. For regular GUIs, see What are MVP and MVC and what is the difference?.)
Traditional MVC for GUI applications
This isn't really relevant to web applications, but here's how MVC traditionally worked in GUI applications:
The model contained the business objects.
The controller responded to UI interactions, and forwarded them to the model.
The view "subscribed" to the model, and updated itself whenever the model changed.
With this approach, you can have (1) multiple ways to update a given piece of data, and (2) multiple ways to view the same data. But you don't have to let every controller know about every view, or vice versa—everybody can just talk to the model.
MVC on the server
Rails, Django and other server-side frameworks all tend to use a particular version of MVC.
The model provides approximately 1 class per database table, and contains most of the business logic.
The view contains the actual HTML for the site, and as little code as possible. Basically, it's just templates.
The controller responds to HTTP requests, processes parameters, looks up model objects, and passes values to the view.
This seems to work very well for server-based web applications, and I've been very happy with it.
MVP on the client
However, if most of your code is written in JavaScript and runs in the web browser, you'll find lots of people using MVP these days. In this case, the roles are a bit different:
The model still contains all the basic entities of your business domain.
The view is a layer of fairly dumb widgets with little logic.
The presenter installs event handlers on the view widgets, it responds to events and it updates the model. In the other direction, the presenter listens for changes to the model, and when those changes occur, it updates the view widgets. So the presenter is a bidirectional pipeline between the model and the view, which never interact directly.
This model is popular because you can easily remove the view layer and write unit tests against the presenter and model. It's also much better suited to interactive applications where everything is updated constantly, as opposed to server applications where you deal with discrete requests and responses.
Here's some background reading:
Martin Fowler's encyclopedic summary of MVC, MVP and related approaches. There's a lot of good history here.
Martin Fowler's description of "Passive View", a variation of MVP.
Google's MVP + event bus
This is a new approach, described in this video from the Google AdWords team. It's designed to work well with caching, offline HTML 5 applications, and sophisticated client-side toolkits like GWT. It's based on the following observations:
Anything might need to happen asynchronously, so design everything to be asynchronous from the very beginning.
Testing browser-based views is much slower than testing models and presenters.
Your real model data lives on the server, but you may have a local cache or an offline HTML 5 database.
In this approach:
The view is very dumb, and you can replace it with mock objects when running unit tests.
The model objects are just simple containers for data, with no real logic. You may have multiple model objects representing the same entity.
The presenter listens to events from the view. Whenever it needs to update or read from the model, it sends an asynchronous message to the server (or to a local caching service). The server responds by sending events to the "event bus". These events contain copies of the model objects. The event bus passes these events back to the various presenters, which update the attached views.
So this architecture is inherently asynchronous, it's easy to test, and it doesn't require major changes if you want to write an HTML 5 offline application. I haven't used it yet, but it's next on my list of things to try. :-)
Both MVP and MVC make sense and allow to separate logic from display.
I would choose MVC because it's widely used in web development these days (Rails, .NET MVC which is used for SO) so my application will be more easily maintainable by someone else. It is also -to me- cleaner (less "power" given to the view), but this is subjective.
Another alternative is MTV, Model-Template-View which Django uses.