I'm reading on design patterns and while authors agree that observer pattern is cool, when it comes to design, everybody talks MVC.
I'm a bit confused, MVC diagram is not circular, isn't it natural for code flow to have closed topology ? Why nobody talking this pattern:
model -> observer -> view -> listener -> model -> ..
If view needs controller, then model needs observer, no ? With Object.observe() coming with next JavaScript version, what is wrong with such a pattern ?
The View and and the Controller are both, also, observers.
The view /is/ an observer, of events on the model. The controller /is/ an observer of events in the view. The controller fires commands at the model, which results in it changing which propagates events which are observed by the view which changes its state appropriately.
The problem this is trying to solve is having a UI respond to changes in a model, and having the model respond to input from a user via a UI. There is no great reason to have a third component involved in this, other than the frailty of human vision -- it is far easier to envision a command and control system than an event driven system, though surprisingly the latter is often easier to implement.
One problem with your proposed design is separation of concerns. With MVC (when done properly, with messages/events) each component only knows about itself and its own concerns. With the model you're proposing the Observer component must know how to orchestrate the view, something which the view is better placed to do itself.
Of course, you're thinking that the controller orchestrates changes to the model, so why wouldn't we have an equivalent component on the far side of the relationship?
In fact, although we do typically implement something in the 'controller' space, it's often just 'infrastructure' to pass messages/events/commands from the view to the model, which responds accordingly -- that is, often the controller devolves into a simple router. The need for an orchestration component has been reduced in modern designs due to our better understanding of DDD and the aggregate-root pattern, and of course the possibilities of event-sourcing.
Finally, the pattern you're referring to was originally documented by the Gang of Four as existing in practice and relatively common. At the time there were no mobile or webapps, and one of the largest systems they considered was gimp. As our technologies have matured and our apps are delivered via multiple channels so have the patterns of development in this space. A few years back we were discussing MVC2, then we moved on to oddities like MVVC and MMVC. Now, with CQRS, event-sourcing, and DDD, we have started talking about MV as the orchestration approach has started showing its limitations and event driven systems come to the fore.
Related
http://examples.ractivejs.org/comments
There is a line in the above example:
// fire an event, so we can (for example)
// save the comment to our server
this.fire( 'newComment', comment );
I'm curious if this is a common practice in Ractive? Firing the event rather than shooting of an AJAX request in the component? Or instantiating some model object and calling a #save method on that object to fire off the request?
Is this separation of concerns? Testing? Just simplified example code?
var user = new Comment({ text: "text is here", author: "author name" });
user.save()
The only thing I can think of is that by firing the event off and letting something else handle it would possibly make testing simpler? It helps with separation of concerns, but it also seems to me like it would make it more difficult to track down who is actually handling the actual creation of the data?
In your opinions, who would handle the firing of the event? In the example it looks like you just tack it on to the "root" ractive instance and let it handle it up there? That seems like it would get really full in a real world application?
Also, as a side question to his one, how often do you find yourself using "models" with ractive on a real world application? Coming from the server-side world, I'm pretty used to thinking of things in terms of classes and domain models. However, the only "model" library I've seen to be popular on front-end side of things is Backbone. However, Backbone seems to be a little overkill for what I'm thinking about?
I'm curious if this is a common practice in Ractive? Firing the event rather than shooting of an AJAX request in the component? Or instantiating some model object and calling a #save method on that object to fire off the request?
Let's say your app needs an <input> element to call an endpoint via AJAX when someone types in something. It's not the <input> that calls the AJAX. It's the surrounding code that hooks on to some known event fired by the input that does the AJAX when the event is fired. Ractive components are given the facilities needed to operate in that way, but you're not necessarily required to do so.
how often do you find yourself using "models" with ractive on a real world application?
Ractive doesn't impose a convention. That's why the authors prefer to call it a library than a framework. You can use any programming pattern you think is necessary. I have used Ractive in the same way React components operate (one-way binding), and I know people who use Ractive merely as a templating engine. What you're provided is a set of API to be able to do stuff. It's up to you how you use it.
If you want to know if Ractive's the only one doing this, that's a no. Several other frameworks do components in one form or another: Ember, Angular (directives), React (Flux + stateless components), Riot, Polymer (web components).
I use backbone in most of my projects, and I think I know exactly what the M V C means: M for abstract of the data, V for representation and C for handlers.
However during my current project I found that there are a lot of views interactive with each other, while there are little modes(data with the server).
For example, I have there complex view named V1 V2 V3, when user do something in the V1, V2 should respond accordingly, so does the V3 and etc, and at the last step, a requst may be made to request data from the server. And most of the request are used to fetch data rather than modify data.
It does not like the common style: one(or more) view for one model such as the CRUD operation.
Now I have two ideas:
1 Virtual model
Create a backbone model to represent the state of the whole application, bind this model to all the views. Sounds like make the application as a state machine.
While it is not easy to describe the application with different states.
2 Use the event mediator
Use the event mediator to register/un-register different events, then the views can trigger or respond by different events.
While how to define the events to avoid insufficien or excessive, in a word to make the events orthogonal is not easy. Or I have not found any instructions yet.
Is there any other alternative solutions?
I think that it is a quite relevant question actually.
Create a backbone model to represent the state of the whole
application, bind this model to all the views. Sounds like make the
application as a state machine.
This doesn't seem like a very good idea, if the model isn't a consistent representation that corresponds to a specific backend resource.
Ideally, a view is a representation of a single model or collection. When a view would be bound to a model with unrelated properties, this doesn't seem too practical to manage in all circumstances, also due to an unforseeable future.
Use the event mediator to register/un-register different events, then
the views can trigger or respond by different events.
I don't think that it is overall a good idea to make views respond to custom events but this is personal for me. When apps become larger, assigning too much responsibility to complex views can become a mess; therefore I take it as a general rule to limit the task of the view to:
Rendering templates;
Activating plugins (if they're specific to the view);
DOM event binding;
(Model binding);
Methods internal to the view (related to the DOM);
Triggering custom events to notify other listeners when further action is required after interaction with the view;
In any case, in my experience I've found that it is practical to use a custom presenter/controller to instantiate / update views on custom events, and not let the view itself worry about these things at all. It keeps them clean and you always know what you will find there.
The views 1, 2 and 3 as you mention can be re-rendered from the presenters.
The presenter does something like:
"I get some data from a service and give it to some of my views that require
them. If something changes, I'll let them know"
I usually have 1 presenter per related set of views.
I like this approach because:
It keeps logic for related views centralised;
When an event is triggered, the presenter needs to listen only once for all the views that it controls;
Presenters are given the authority to talk to each other, which is to my feeling easier to control than when all views would start talking to each other through each other;
In simple cases, all of this doesn't matter too much probably. But when building a larger application, I found that it can become a mess.
My two cents
I have there complex view named V1 V2 V3, when user do something in the V1, V2 should respond accordingly, so does the V3 and etc
It doesn't seem like you have 3 views, but in fact 1 view with 3 interrelated sections. I would use one super view that renders 3 child views, and listen to view events. For example:
Backbone.View.extend({
initialize: function () {
this.v1 = ...;
this.v2 = ...;
this.v3 = ...;
this.v1.on('user do something', this.v2.respondAccordingly);
this.v1.on('user do something', this.v3.soDoesEtc);
}
})
And in view 1:
$('button').on('click', function () {
self.trigger('user do something');
})
This is a problem that many Backbone developers face.
What I've done in the past is to have a baseModel/baseCollection, and treat them as an abstract class/interface from which other models/collections extend, respectfully. These base objects would contain a listener/trigger methods which I could then use across my application to have changes in one model/collection be able to initiate updates on collections/models (thus triggering view changes) respectively as I chose. Using this method allowed me to compose my application by having the appropriate objects listen/broadcast events appropriately as I wished.
One of my friends created a server-side JS state machine which would initiate super-models (app-level model which in turn could trigger sub-view model/collection updates).
Of course, Marionette provides a framework that makes this a little less manual and allows you to get back to writing app-code.
One of the joys and burdens of Backbone.js is that you have all the flexibility you want. :)
I'm pretty new to this world so I need some clarifications on it. Maybe I could be wrong on the subject. So, feel free to correct me.
I'm studying how Marionette and Backbone work together. Oh yeah. Marionette gives us extension to Backbone. Really nice stuff.
The thing that is not obvious to me is when to use the routing mechanism provided by Backbone and when to use publisher/subscriber pattern by Marionette.
Is there any rule of thumb?
Here, Where to use event aggregator in backbone marionette?, a similar discussion but there is no advice on how using that or the other.
My take on the route management is explained in the free preview to my book on Marionette (http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf)
Basically, my opinion (others don't necessarily share it) is that Backbone's routing should be used to configure the application state when the user "enters" the application via a URL. In other words, it will parse parameters, and call proper controller actions.
But once that initial state is setup, routing code should no longer be triggered, even as the user navigates through the application.
Here's an example:
The user enters arrives on the "contacts/2/edit". Backbone routing code will extract the 2 argument and call the edit controller action with that id parameter (which fetches that contact, displays the proper views, etc.). In other words, the initial application state is being configured.
The user clicks on the "show all contacts" link leading to the "contacts" URL. Here, I believe this modification should be handled through Marionette events (i.e. indicating the user wants to see all contacts). After all, we know what the user wants to do, and which URL fragment should be displayed. In other words, there is no reason for the routing code to get involved.
Note that this is my opinion, and other developers simply pass trigger: true when the user clicks a link. But as I explain in the book extract linked above, this tends to lead developers to create "stateless applications in javascript" (e.g. passing lots of parameters in the URL, even though they should be stored in the application's state). Ater all there is a reason that by default, Backbone's navigate method has trigger: false.
Derick Bailey (Marionette's creator) also discussed the issue here: http://lostechies.com/derickbailey/2011/08/03/stop-using-backbone-as-if-it-were-a-stateless-web-server/
Event aggregator is more useful for notifying things. (think small bits of feedback)
Message from server (updated record)
Let other models know things have changed
Lock everything down while saving until saved
Single Moment in time things
Router is for things where you want the state to be save-able (think separate page in a MPA)
Model Edit Page
Model View Page
Something that will stay until another event or activity changes it
If you are not sure if something is an event or a page, then think about it and ask that separate question.
The StateManager in Ember.js isn't that well documented yet, so I've got some questions regarding its usage.
Should one strive to call .goToState only from within the state manager?
I sometimes find myself mirroring methods in the state manager on the view, e.g. save: -> StateManager.send("save"). Does that make sense or am I missing something?
Should all modification of models (generally) go through the state manager?
If one view has different states, should that be modeled using a ViewState with child states, or should I use computed properties and view properties to hold that information only in the view (without the state manager knowing of the views internal state)?*
*One example could be a three-step form, where the same template is used for all states but different areas are shown/hidden in the three steps.
Github reference: https://github.com/emberjs/ember.js/tree/master/packages/ember-states/lib
Should one strive to call .goToState only from within the state
manager?
Probably. I don't know this for certain, but it seems to me that because the state manager knows what state you're in, it's the place to enforce legal state transitions. If you called .goToState from outside the state manager, you're doing it without really knowing what state you're in, and while that's sometimes OK (maybe it's a state you really can reach from any other state) it's not a great habit to be in.
I sometimes find myself mirroring methods in the state
manager on the view, e.g. save: -> StateManager.send("save"). Does
that make sense or am I missing something?
I like what pangratz has to say about this.
Should all modification of
models (generally) go through the state manager?
The way I use statecharts, no. I've seen some people using statecharts as pretty much a complete replacement for the controller layer, however, and if that's how you're working, then yes, it should go through the state manager. The pattern is to avoid direct manipulation of models from views; whether it's a controller layer or a state manager in between seems like a moot point to me.
The way I use state charts, however, the state manager is made to manage the state of the application. It can play traffic manager for the modification of models if that modification will change the state of the application (e.g. if there's a progress indicator while an update completes), but it seems to me that model updates aren't part of its mandate; they belong to controllers.
If one view has
different states, should that be modeled using a ViewState with child
states, or should I use computed properties and view properties to
hold that information only in the view (without the state manager
knowing of the views internal state)?
I think the state manager needs to know (or ought to know) the view's internal state.
Out of curiosity, are you coming from a web development background, or a desktop/mobile app development background? I came from web development, and state charts were a new concept for me. I found it very useful to read the canonical State Chart paper by David Harel ('ware PDF!). It's surprisingly readable for an academic paper and lays out the basic state chart concept most of the SproutCore/Ember world has been using since late 2010 (i.e. it's what Michael Cohen had in mind when he wrote Ki.)
Regarding your point 2:
I sometimes find myself mirroring methods in the state manager on the view, e.g. save: -> StateManager.send("save"). Does that make sense or am I missing something?
You could use the action helper in your Handlebars template and set your StateManager as target
{{action "send" target="App.stateManager"}}
And the the send event is send to your App.stateManager.
Hey all, I'm looking at building an ajax-heavy site, and I'm trying to spend some time upfront thinking through the architecture.
I'm using Code Igniter and jquery. My initial thought process was to figure out how to replicate MVC on the javascript side, but it seems the M and the C don't really have much of a place.
A lot of the JS would be ajax calls BUT I can see it growing beyond that, with plenty of DOM manipulation, as well as exploring the HTML5 clientside database. How should I think about architecting these files? Does it make sense to pursue MVC? Should I go the jquery plugin route somehow? I'm lost as to how to proceed and I'd love some tips. Thanks all!
I've made an MVC style Javascript program. Complete with M and C. Maybe I made a wrong move, but I ended up authoring my own event dispatcher library. I made sure that the different tiers only communicate using a message protocol that can be translated into pure JSON objects (even though I don't actually do that translation step).
So jquery lives primarily in the V part of the MVC architecture. In the M, and C side, I have primarily code which could run in the stand alone CLI version of spidermonkey, or in the serverside rhino implementation of javascript, if necessary. In this way, if requirements change later, I can have my M and C layers run on the serverside, communicating via those json messages to the V side in the browser. It would only require some modifications to my message dispatcher to change this though. In the future, if browsers get some peer to peer style technologies, I could get the different teirs running in different browsers for instance.
However, at the moment, all three tiers run in a single browser. The event dispatcher I authored allows multicast messages, so implementing an undo feature now will be as simple as creating a new object that simply listens to the messages that need to be undone. Autosaving state to the server is a similar maneuver. I'm able to do full detailed debugging and profiling inside the event dispatcher. I'm able to define exactly how the code runs, and how quickly, when, and where, all from that central bit of code.
Of course the main drawback I've encountered is I haven't done a very good job of managing the complexity of the thing. For that, if I had it all to do over, I would study very very carefully the "Functional Reactive" paradigm. There is one existing implementation of that paradigm in javascript called flapjax. I would ensure that the view layer followed that model of execution, if not used specifically the flapjax library. (i'm not sure flapjax itself is such a great execution of the idea, but the idea itself is important).
The other big implementation of functional reactive, is quartz composer, which comes free with apple's developer tools, (which are free with the purchase of any mac). If that is available to you, have a close look at that, and how it works. (it even has a javascript patch so you can prototype your application with a prebuilt view layer)
The main takaway from the functional reactive paradigm, is to make sure that the view doesn't appear to maintain any kind of state except the one you've just given it to display. To put it in more concrete terms, I started out with "Add an object to the screen" "remove an object from the screen" type messages, and I'm now tending more towards "display this list of objects, and I'll let you figure out the most efficient way to get from the current display, to what I now want you to display". This has eliminated a whole host of bugs having to do with sloppily managed state.
This also gets around another problem I've been having with bugs caused by messages arriving in the wrong order. That's a big one to solve, but you can sidestep it by just sending in one big package the final desired state, rather than a sequence of steps to get there.
Anyways, that's my little rant. Let me know if you have any additional questions about my wartime experience.
At the risk of being flamed I would suggest another framework besides JQuery or else you'll risk hitting its performance ceiling. Its ala-mode plugins will also present a bit of a problem in trying to separate you M, V and C.
Dojo is well known for its Data Stores for binding to server-side data with different transport protocols, and its object oriented, lighting fast widget system that can be easily extended and customized. It has a style that helps guide you into clean, well-divisioned code – though it's not strictly MVC. That would require a little extra planning.
Dojo has a steeper learning curve than JQuery though.
More to your question, The AJAX calls and object (or Data Store) that holds and queries this data would be your Model. The widgets and CSS would be your View. And the Controller would basically be your application code that wires it all together.
In order to keep them separate, I'd recommend a loosely-coupled event-driven system. Try to directly access objects as little as possible, keeping them "black boxed" and get data via custom events or pub/sub topics.
JavaScriptMVC (javascriptmvc.com) is an excellent choice for organizing and developing a large scale JS application.
The architecture design is very practical. There are 4 things you will ever do with JavaScript:
Respond to an event
Request Data / Manipulate Services (Ajax)
Add domain specific information to the ajax response.
Update the DOM
JMVC splits these into the Model, View, Controller pattern.
First, and probably the most important advantage, is the Controller. Controllers use event delegation, so instead of attaching events, you simply create rules for your page. They also use the name of the Controller to limit the scope of what the controller works on. This makes your code deterministic, meaning if you see an event happen in a '#todos' element you know there has to be a todos controller.
$.Controller.extend('TodosController',{
'click' : function(el, ev){ ... },
'.delete mouseover': function(el, ev){ ...}
'.drag draginit' : function(el, ev, drag){ ...}
})
Next comes the model. JMVC provides a powerful Class and basic model that lets you quickly organize Ajax functionality (#2) and wrap the data with domain specific functionality (#3). When complete, you can use models from your controller like:
Todo.findAll({after: new Date()}, myCallbackFunction);
Finally, once your todos come back, you have to display them (#4). This is where you use JMVC's view.
'.show click' : function(el, ev){
Todo.findAll({after: new Date()}, this.callback('list'));
},
list : function(todos){
$('#todos').html( this.view(todos));
}
In 'views/todos/list.ejs'
<% for(var i =0; i < this.length; i++){ %>
<label><%= this[i].description %></label>
<%}%>
JMVC provides a lot more than architecture. It helps you in ever part of the development cycle with:
Code generators
Integrated Browser, Selenium, and Rhino Testing
Documentation
Script compression
Error reporting
I think there is definitely a place for "M" and "C" in JavaScript.
Check out AngularJS.
It helps you with your app structure and strict separation between "view" and "logic".
Designed to work well together with other libs, especially jQuery.
Full testing environment (unit, e2e) + dependency injection included, so testing is piece of cake with AngularJS.
There are a few JavaScript MVC frameworks out there, this one has the obvious name:
http://javascriptmvc.com/