OLD | NEW |
(Empty) | |
| 1 <h1 class="page_title">MVC Architecture</h1> |
| 2 <div id="pageData-showTOC" class="pageData">true</div> |
| 3 <p> |
| 4 As modern browsers become more powerful with rich features, |
| 5 building full-blown web applications in JavaScript is not only feasible, |
| 6 but increasingly popular. |
| 7 Based on |
| 8 <a href="http://httparchive.org/trends.php?s=intersection&minlabel=Jan+20+2011&m
axlabel=Jan+15+2012">trends</a> |
| 9 on <a href="http://httparchive.org/">HTTP Archive</a>, |
| 10 deployed JavaScript code size has grown 45% over the course of the year. |
| 11 </p> |
| 12 <img src="{{static}}/images/jstransferrequests.png" |
| 13 width="568" |
| 14 height="292" |
| 15 alt="JS transfer size and JS requests"> |
| 16 <p> |
| 17 With JavaScript's popularity climbing, |
| 18 our client-side applications are much more complex than before. |
| 19 Application development requires collaboration from multiple developers. |
| 20 Writing <strong>maintainable</strong> and |
| 21 <strong>reusable</strong> code is crucial in the new web app era. |
| 22 The Chrome packaged app, with its rich client-side features, is no exception. |
| 23 </p> |
| 24 <p> |
| 25 Design patterns are important to write maintainable and reusable code. |
| 26 A pattern is a reusable solution that can be applied to commonly occurring probl
ems in software design — |
| 27 in our case — writing Chrome packaged apps. |
| 28 We recommend that developers decouple the app |
| 29 into a series of independent components following the MVC pattern. |
| 30 </p> |
| 31 <p> |
| 32 In the last few years, |
| 33 a series of JavaScript MVC frameworks have been developed, |
| 34 such as <a href="http://backbonejs.org/">backbone.js</a>, <a href="http://emberj
s.com/">ember.js</a>, <a href="http://angularjs.org/">AngularJS</a>, <a href="ht
tp://sencha.com/">Sencha</a>, <a href="http://kendo.com/">Kendo UI</a>, and more
. |
| 35 While they all have their unique advantages, each one of them follows some form
of MVC pattern |
| 36 with the goal of encouraging developers to write more structured JavaScript code
. |
| 37 </p> |
| 38 <h2 id="mvc">MVC pattern overview</h2> |
| 39 <p> |
| 40 MVC offers architectural benefits over standard JavaScript — |
| 41 it helps you write better organized, and therefore more maintainable code. |
| 42 This pattern has been used and extensively tested |
| 43 over multiple languages and generations of programmers. |
| 44 </p> |
| 45 <p> |
| 46 MVC is composed of three components: |
| 47 </p> |
| 48 <img src="{{static}}/images/mvc.png" |
| 49 width="466" |
| 50 height="303" |
| 51 alt="model-view-controller"> |
| 52 <h3>Model</h3> |
| 53 <p> |
| 54 Model is where the application’s data objects are stored. |
| 55 The model doesn’t know anything about views and controllers. |
| 56 When a model changes, typically it will notify its observers that a change has o
ccurred. |
| 57 </p> |
| 58 <p> |
| 59 To understand this further, let’s use the Todo list app, a simple, one page web
app that tracks your task list. |
| 60 </p> |
| 61 <br> |
| 62 <img src="{{static}}/images/todos.png" |
| 63 width="444" |
| 64 height="366" |
| 65 alt="model-view-controller"> |
| 66 <p> |
| 67 The model here represents attributes associated |
| 68 with each todo item such as description and status. |
| 69 When a new todo item is created, |
| 70 it is stored in an instance of the model. |
| 71 </p> |
| 72 <h3>View</h3> |
| 73 <p> |
| 74 View is what's presented to the users and how users interact with the app. |
| 75 The view is made with HTML, CSS, JavaScript and often templates. |
| 76 This part of your Chrome packaged app has access to the DOM. |
| 77 </p> |
| 78 <p> |
| 79 For example, in the above todo list web app, |
| 80 you can create a view that nicely presents the list of todo items to your users. |
| 81 Users can also enter a new todo item through some input format; |
| 82 however, the view doesn’t know how to update the model because that’s the contro
ller’s job. |
| 83 </p> |
| 84 <h3>Controller</h3> |
| 85 <p> |
| 86 The controller is the decision maker and the glue between the model and view. |
| 87 The controller updates the view when the model changes. |
| 88 It also adds event listeners to the view and |
| 89 updates the model when the user manipulates the view. |
| 90 </p> |
| 91 <p> |
| 92 In the todo list web app, |
| 93 when the user checks an item as completed, |
| 94 the click is forwarded to the controller. |
| 95 The controller modifies the model to mark item as completed. |
| 96 If the data needs to be persistent, it also makes an async save to the server. |
| 97 In rich client-side web app development such as Chrome packaged apps, |
| 98 keeping the data persistent in local storage is also crucial. |
| 99 In this case, the controller also handles saving the data |
| 100 to the client-side storage such as <a href="app_storage.html">FileSystem API</a>
. |
| 101 </p> |
| 102 <p> |
| 103 There are a few variations of the MVC design pattern |
| 104 such as MVP (Model–View–Presenter) |
| 105 and MVVP(Model–View–ViewModel). |
| 106 Even with the so called MVC design pattern itself, |
| 107 there is some variation between the traditional MVC pattern |
| 108 vs the modern interpretation in various programming languages. |
| 109 For example, some MVC–based frameworks will have |
| 110 the view observe the changes in the models |
| 111 while others will let the controller handle the view update. |
| 112 This article is not focused on the comparison of various implementations |
| 113 but rather on the separation–of–concerns and |
| 114 it's importance in writing modern web apps. |
| 115 </p> |
| 116 <p> |
| 117 If you are interested in learning more, |
| 118 we recommend <a href="https://plus.google.com/u/0/115133653231679625609/posts">A
ddy Osmani's</a> online book: <a href="http://addyosmani.com/resources/essential
jsdesignpatterns/book/">Learning JavaScript Design Patterns</a>. |
| 119 </p> |
| 120 <p> |
| 121 To summarize, the MVC pattern brings modularity |
| 122 to application developers and it enables: |
| 123 </p> |
| 124 <ul> |
| 125 <li>Reusable and extendable code.</li> |
| 126 <li>Separation of view logic from business logic.</li> |
| 127 <li>Allow simultaneous work between developers who are responsible |
| 128 for different components (such as UI layer and core logic).</li> |
| 129 <li>Easier to maintain.</li> |
| 130 </ul> |
| 131 <h2 id="mvcpersistence">MVC persistence patterns</h2> |
| 132 <p> |
| 133 There are many different ways of implementing persistence |
| 134 with an MVC framework, each with different trade–offs. |
| 135 When writing Chrome packaged apps, |
| 136 choose the frameworks with MVC and persistence patterns |
| 137 that feel natural to you and fit you application needs. |
| 138 </p> |
| 139 <h3>Model does its own persistence - ActiveRecord pattern</h3> |
| 140 <p> |
| 141 Popular in both server–side frameworks like Ruby on Rails, |
| 142 and client-side frameworks like |
| 143 <a href="http://backbonejs.org">Backbone.js</a> and |
| 144 <a href="http://emberjs.com/">ember.js</a>, |
| 145 the ActiveRecord pattern places the responsibility |
| 146 for persistence on the model itself |
| 147 and is typically implemented via JSON API. |
| 148 </p> |
| 149 <p> |
| 150 A slightly different take from |
| 151 having a model handle the persistence |
| 152 is to introduce a separate concept of Store and Adapter API. |
| 153 Store, Model and |
| 154 Adapter (in some frameworks it is called Proxy) |
| 155 work hand by hand. |
| 156 Store is the repository that holds the loaded models, |
| 157 and it also provides functions such as creating, |
| 158 querying and filtering the model instances contained within it. |
| 159 </p> |
| 160 <p> |
| 161 An adapter, or a proxy, receives the requests from a store and |
| 162 translates them into appropriate actions to take |
| 163 against your persistent data layer |
| 164 (such as JSON API). |
| 165 This is interesting in the modern web app design |
| 166 because you often interact with more than one persistent data layer |
| 167 such as a remote server and browser’s local storage. |
| 168 Chrome package apps provides both |
| 169 <a href="storage.html">Chrome Storage API</a> and |
| 170 <a href="fileSystem.html">HTML 5 fileSystem API</a> for client side storage. |
| 171 </p> |
| 172 <p>Pros:</p> |
| 173 <ul> |
| 174 <li>Simple to use and understand.</li> |
| 175 </ul> |
| 176 <p> |
| 177 Cons: |
| 178 </p> |
| 179 <ul> |
| 180 <li>Hard to test since the persistence layer is ‘baked’ into the object
hierarchy.</li> |
| 181 <li>Having different objects use different persistent stores is difficul
t |
| 182 (for example, FileSystem APIs vs indexedDB vs server–side)
.</li> |
| 183 <li>Reusing Model in other applications may create conflicts, |
| 184 such as sharing a single Customer class between two different vi
ews, |
| 185 each view wanting to save to different places.</li> |
| 186 </ul> |
| 187 <h3>Controller does persistence</h3> |
| 188 <p> |
| 189 In this pattern, the controller holds a reference |
| 190 to both the model and a datastore |
| 191 and is responsible for keeping the model persisted. |
| 192 The controller responds to lifecycle events like Load, Save, Delete, |
| 193 and issues commands to the datastore to fetch or update the model. |
| 194 </p> |
| 195 <p> |
| 196 Pros: |
| 197 </p> |
| 198 <ul> |
| 199 <li>Easier to test, controller can be passed a mock datastore to write t
ests against.</li> |
| 200 <li>The same model can be reused with multiple datastores just by constr
ucting controllers with different datastores.</li> |
| 201 </ul> |
| 202 <p> |
| 203 Cons: |
| 204 </p> |
| 205 <ul> |
| 206 <li>Code can be more complex to maintain.</li> |
| 207 </ul> |
| 208 <h3>AppController does persistence</h3> |
| 209 <p> |
| 210 In some patterns, there is a supervising controller responsible |
| 211 for navigating between one MVC and another. |
| 212 The AppController decides, for example, |
| 213 that a ‘Back’ button moves the client from an editing screen |
| 214 (which contains MVC widgets/formats), |
| 215 to a settings screen. |
| 216 </p> |
| 217 <p> |
| 218 In the AppController pattern, |
| 219 the AppController responds to events |
| 220 and changes the app’s current screen by issuing a call |
| 221 to the datastore to load any models needed and |
| 222 constructing all of the matching views and controllers for that screen. |
| 223 </p> |
| 224 <p> |
| 225 Pros: |
| 226 </p> |
| 227 <ul> |
| 228 <li>Moves persistence layer even higher up the stack where it can be eas
ily changed.</li> |
| 229 <li>Doesn’t pollute lower level controllers like a DatePickerController
with the need to know about persistence.</li> |
| 230 <li>Aligns nicely with an ‘Intent’ model. |
| 231 Each AppController corresponds to an intent, like “ChoosePhoto”,
or “SendMessage”. |
| 232 The Intent contains a reference to the model data needed (Custom
er#123) and |
| 233 the type of CRUD operation (load, save, delete, and so on).</li> |
| 234 </ul> |
| 235 <p> |
| 236 Cons: |
| 237 </p> |
| 238 <ul> |
| 239 <li>Each ‘Page/Screen’ of the app now requires a lot of boilerplate to w
rite or update: Model, View, Controller, AppController.</li> |
| 240 </ul> |
| 241 <h3>Recommended MVC frameworks</h3> |
| 242 <p> |
| 243 MVC is crucial to designing Chrome packaged apps. |
| 244 We recommend the following <a href="app_csp.html">CSP–Compliant</a> MVC fr
ameworks |
| 245 for writing secure and scalable Chrome packaged apps: |
| 246 </p> |
| 247 <ul> |
| 248 <li><a href="http://angularjs.org/">AngularJS</a> |
| 249 (<a href="https://github.com/GoogleChrome/textdrive-app">Text Dr
ive Reference App</a>)</li> |
| 250 <li><a href="http://kendo.com/">Kendo UI</a> |
| 251 (<a href="https://github.com/GoogleChrome/kendo-photo-booth-app"
>Photo Booth Reference App</a>)</li> |
| 252 <li><a href="http://www.sencha.com/">Sencha</a> |
| 253 (<a href="https://github.com/GoogleChrome/sencha-video-player-ap
p">Video Player Reference App</a>)</li> |
| 254 </ul> |
| 255 <h2 id="resources">Useful resources</h2> |
| 256 <h3>Online</h3> |
| 257 <ul> |
| 258 <li><a href="http://www.html5rocks.com/">HTML5Rocks.com</a></li> |
| 259 <li><a href="http://addyosmani.com/resources/essentialjsdesignpatterns/b
ook/">Learning JavaScript Design Patterns</a> |
| 260 (by Addy Osmani)</li> |
| 261 <li><a href="http://addyosmani.github.com/todomvc/">TodoMVC</a></li> |
| 262 </ul> |
| 263 <h3>Books</h3> |
| 264 <ul> |
| 265 <li><a href="http://www.amazon.com/JavaScript-Web-Applications-Alex-MacC
aw/dp/144930351X">JavaScript Web Applications</a> |
| 266 (By Alex MacCaw)</li> |
| 267 <li><a href="http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/d
p/0596806752/ref=pd_sim_b_2">JavaScript Patterns</a> |
| 268 (By Stoyan Stefonov)</li> |
| 269 <li><a href="http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Za
kas/dp/1449327680">Maintainable JavaScript</a> |
| 270 (By Nicolas Z. Zakas)</li> |
| 271 </ul> |
| 272 <p class="backtotop"><a href="#top">Back to top</a></p> |
OLD | NEW |