<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" gd:etag="W/&quot;D0YBQX4ycCp7ImA9WhFSFEs.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779</id><updated>2013-06-17T10:32:30.098Z</updated><category term="ruby" /><category term="winforms" /><category term="ironpython" /><category term="resource_controller" /><category term="webrat" /><category term="ajax" /><category term="resolver" /><category term="selenium" /><category term="google spreadsheets" /><category term="attachment-fu" /><category term="rspec" /><category term="spreadsheet" /><category term="git" /><category term="groovy" /><category term="python" /><category term="nginx" /><category term="migrations" /><category term="rails" /><category term="mongrel" /><category term="dsl" /><category term="euruko2008" /><category term="rmagick" /><category term=".net" /><category term="tdd" /><category term="jruby" /><category term="bdd" /><category term="capistrano" /><category term="chess" /><category term="rake" /><title>Andrzej on Software</title><subtitle type="html">Thoughts on software</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>95</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/andrzejkrzywda" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="andrzejkrzywda" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUACSXc6fyp7ImA9WhFSFEs.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-1590718412069815260</id><published>2013-06-17T10:09:00.000Z</published><updated>2013-06-17T10:09:28.917Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-06-17T10:09:28.917Z</app:edited><title>Typical Rails bugs</title><content type="html">As part of my &lt;a href="http://arkency.com/report/"&gt;research on improving Rails application&lt;/a&gt;, I noticed a pattern in the bugs that are quite characteristic to Rails in several applications.&lt;br /&gt;
&lt;br /&gt;
They have certain 'visible' things in common:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;often security related, like leaking some information to unauthorized users&lt;/li&gt;
&lt;li&gt;they live somewhere in the area of business logic/persistence&lt;/li&gt;
&lt;li&gt;they are not so easy to fix in the existing codebase&lt;/li&gt;
&lt;li&gt;they tend to exist in groups, similar bugs in different areas&lt;/li&gt;
&lt;li&gt;they are easy to miss&lt;/li&gt;
&lt;li&gt;often they appear during the requirements changes&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Overdose of ActiveRecord&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The reasons they exist is a combination of different things. The main common point of the bugs is the over-usage of ActiveRecord. It's easy to fall into this problem, I did it many times, as well.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
You start with a new Rails app, adding new features very quickly. New requirements pop up. You use the popular Rails techniques to deal with them:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;validations, which often turn into conditional validations&lt;/li&gt;
&lt;li&gt;Single Table Inheritance&lt;/li&gt;
&lt;li&gt;state-machine&lt;/li&gt;
&lt;li&gt;accept_nested_attributes&lt;/li&gt;
&lt;li&gt;models callbacks&lt;/li&gt;
&lt;li&gt;virtual attributes&lt;/li&gt;
&lt;li&gt;external gems that provide value magically, by using ActiveRecord (implicit dependencies)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
Every technique is fine on its own. When you start using all of them in the same area, problems appear.&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Examples&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
I started noticing this trend, while reviewing the code of our potential &lt;a href="http://arkency.com/"&gt;Arkency&lt;/a&gt; customers. We sometimes do the "rescue missions" and help with legacy code. I can't use those examples here, so I started reviewing some of the popular open-source Rails applications: Discourse, Spree, Redmine, Gitlab. It didn't take me much time to discover the same bugs.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Just to be clear, all of the projects are awesome and I'm grateful to the people behind them.&lt;/b&gt; Most of the times, they deal with this kind of problems very quickly. I don't want to blame them for anything - they just serve here as examples.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Discourse&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Let's start with Discourse:&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;1. Digest mail ignores secure groups&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://meta.discourse.org/t/digest-mail-ignores-secure-groups/7288"&gt;http://meta.discourse.org/t/digest-mail-ignores-secure-groups/7288&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;People receiving the digest mail can easily read posts not meant for them. That's because the digest mail ignores the secure groups a member has access to or not.&lt;br /&gt;Quite a problem as I unfortunately found out.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Non-authenticated users see private topics in 404 page&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://meta.discourse.org/t/non-authenticated-users-see-private-topics-in-404-page-was-mobile-view/7419"&gt;http://meta.discourse.org/t/non-authenticated-users-see-private-topics-in-404-page-was-mobile-view/7419&lt;/a&gt;&lt;br /&gt;
&lt;i&gt;&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
Discourse correctly prevented me from seeing the topic and instead showed a 404 page. On that 404 page, the lists of "Latest Topics" and "Recent Topics" showed private topics. I could click those links, which resulted in seeing the same 404 page again.&lt;br /&gt;The 404 page should not show private topics.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Auto-suggest topics shows private topics&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://meta.discourse.org/t/auto-suggest-topics-shows-private-topics/7418/3"&gt;http://meta.discourse.org/t/auto-suggest-topics-shows-private-topics/7418/3&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;We've got Discourse running with private categories. When a user without access to the private categories type a new topic, they are presented with topics in categories to which they don't have access.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Comment: &lt;/b&gt;Did you notice the pattern here?&lt;br /&gt;
&lt;br /&gt;
Accidentally, I've had a &lt;a href="https://news.ycombinator.com/item?id=5889651"&gt;small conversation at HN&lt;/a&gt; with one of the Discourse founders. He said:&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;br /&gt;Those private topic bugs are not the result of ActiveRecord. We added a group layer on top of existing code and missed some places where queries did not respect it.&lt;br /&gt;&lt;br /&gt;Had we used raw SQL instead of an ORM we would have had the same issues. All projects are open to this style of bug. The correct thing to do is report, close them quickly and add tests to prevent them from happening again (which we do.)&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
I have completely no 'science' proof here, it's just based on my experience with hundreds of Rails projects. However, I disagree that all projects are open to this style of bug.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;It's very typical to Rails projects.&amp;nbsp;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The temptation of globally accessing every model/record from every place in the project makes it very easy to introduce such bugs. When you add new requirements (as they did) it's practically impossible to find all the places which should be changed.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Do I blame ActiveRecord here? No, ActiveRecord is a good library for persistence. It has its issues, it's huge, even the maintainers consider it a legacy code. Apart from some edge cases, it works more or less ok. I think the problem is relying on ActiveRecord for basically everything.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Spree&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Let's see some other bugs, this time in Spree:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;1. Fix wrong discount calculation with flat percent promotions&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://github.com/spree/spree/pull/3054"&gt;https://github.com/spree/spree/pull/3054&lt;/a&gt;&lt;/div&gt;
&lt;i&gt;&lt;br /&gt;&lt;br /&gt; Fix wrong discount calculation with flat percent promotions when there are more than one line item in the order.&lt;br /&gt;&lt;br /&gt;This error happened because the order instance here:&lt;br /&gt;&lt;a href="https://github.com/spree/spree/blob/master/core/app/models/spree/order_updater.rb#L24"&gt;https://github.com/spree/spree/blob/master/core/app/models/spree/order_updater.rb#L24&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;is not always the same instance in memory here:&lt;br /&gt;&lt;a href="https://github.com/spree/spree/blob/master/core/app/models/spree/calculator/flat_percent_item_total.rb#L15"&gt;https://github.com/spree/spree/blob/master/core/app/models/spree/calculator/flat_percent_item_total.rb#L15&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Adding the inverse option to the relationship makes sure you have the same object instance in both places.&lt;/i&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Comment: &lt;/b&gt;Here we have another problem related to ActiveRecord. In more complex situations (cyclic associations), you can have the same 'record' in memory as two different instances, leading to errors.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;2. Admin products loads entire dataset to determine the total count when paginating&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://github.com/spree/spree/issues/2679"&gt;https://github.com/spree/spree/issues/2679&lt;/a&gt;&lt;/div&gt;
&lt;i&gt;&lt;br /&gt;When kaminary determines the total count of records it runs the following code&lt;br /&gt;@collection.except(:offset, :limit, :order).count
&lt;br /&gt;&lt;br /&gt;The issue is that this sequence loads entire dataset to determine the count. This makes heavy load when products have large number of items.&lt;br /&gt;&lt;br /&gt;The reason of this behaviour is group_by_products_id here &lt;a href="https://github.com/spree/spree/blob/1-2-stable/core/app/controllers/spree/admin/products_controller.rb#L94"&gt;https://github.com/spree/spree/blob/1-2-stable/core/app/controllers/spree/admin/products_controller.rb#L94&lt;/a&gt;&lt;/i&gt;&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Comment: &lt;/b&gt;This time we have a combination of ActiveRecord and an external gem - kaminari (paginator). The end result is slowness of admin panels with thousands of products - they all will be loaded to memory. It's not the worst bug I've seen, but it's typical.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;3. Default Tax Does Not Calculate Taxes Correctly if there is a Promotion&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://github.com/spree/spree/issues/2493"&gt;https://github.com/spree/spree/issues/2493&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;4. Taxes should be re-calculated after promotion adds an adjustment&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="https://github.com/spree/spree/issues/1735"&gt;https://github.com/spree/spree/issues/1735&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Comment&lt;/b&gt;: the titles should be enough. This kind of bugs is usually related to the ActiveRecord callbacks usage. In complex scenarios it's not that easy to track all the places that need to be called after some changes.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Redmine&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Let's now look at one Redmine bug:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;1. Time entries of private issues are visible by users without permission to see them&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href="http://www.redmine.org/issues/12287"&gt;http://www.redmine.org/issues/12287&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Comment: &lt;/b&gt;Does it ring a bell? Again, a leak of private information.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
We have seen some of the bugs, that I called &lt;b&gt;typical Rails bugs&lt;/b&gt;. They seem to have certain things in common. I've seen them so many times, that they are the first things I look for, when I get access to a new project ticketing system.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Is there any way of defending against them? I think so. The best step to start with is to be aware of such problems. Try to spot them in your projects, see what history is behind the bug, spread the knowledge in your team.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
In my next blog posts, I'll focus on techniques that should help decrease the number of such bugs. Stay tuned. In the meantime, &lt;a href="https://twitter.com/andrzejkrzywda"&gt;you may want to follow me on Twitter&lt;/a&gt;&amp;nbsp;and &lt;a href="http://arkency.com/report/"&gt;subscribe to the Rails Architectures Guide&lt;/a&gt;, that I'm working on.&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/1590718412069815260/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=1590718412069815260" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1590718412069815260?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1590718412069815260?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/06/typical-rails-bugs.html" title="Typical Rails bugs" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUUEQXkyeyp7ImA9WhBUEUk.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-6326759586549000062</id><published>2013-04-28T10:00:00.000Z</published><updated>2013-04-28T10:00:00.793Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-28T10:00:00.793Z</app:edited><title>Single Page Applications fight - video</title><content type="html">During the last &lt;a href="http://wrocloverb.com/"&gt;wroc_love.rb&lt;/a&gt; conference we've organised a "fight" between 4 different approaches to Single Page Applications. Below is the video (0.5h) and a very short and simplified transcript from this event.&lt;br /&gt;
&lt;br /&gt;
The participants, from the left-side:&lt;br /&gt;
&lt;br /&gt;
Patrick Mulder - Backbone&lt;br /&gt;
Piotr Sarnacki &amp;nbsp;- Ember&lt;br /&gt;
Andrzej Krzywda (me) - Hexagonal&lt;br /&gt;
Adam Pohorecki - Angular&lt;br /&gt;
&lt;br /&gt;
moderator - Jan Filipowski&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/h8XeZFW1Ad0" width="560"&gt;&lt;/iframe&gt;






&lt;br /&gt;
&lt;div class="p1"&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p2"&gt;
1m39s&lt;/div&gt;
&lt;div class="p1"&gt;
&lt;b&gt;Can anything be a Single Page App?&lt;/b&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;(and discussion about SEO)&lt;/b&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Patrick&lt;/b&gt;: only for some apps&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Drogus&lt;/b&gt;: for interactive apps, not for static apps that need to be indexed by Google&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: for all the apps&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adam&lt;/b&gt;: we need better tools on the backend in order to have a better developer experience&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Piotr&lt;/b&gt;: Andrzej, would you write wikipedia as a SPA?&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: Yes.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adam&lt;/b&gt;: What about SEO?&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: It's a myth that SPAs are not indexable. Google has an official document for that. It is additional work.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Patrick&lt;/b&gt;: You can use PhantomJS for SEO.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adam&lt;/b&gt;: We've used PhantomJS for that, took a couple of hours.&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;
8m28s&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Can you introduce the framework you're representing here?&lt;/b&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: HexagonalJS is not a framework, it's an architecture guide. Uncle Bob (OOP) + Raganwald (AOP) + Hexagonal Architecture. It's more like a set of guidelines&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Piotr&lt;/b&gt;: EmberJS - it does as much as it can for managing your SPA. it's not minimalistic, for good reasons (you don't have to write much code).&amp;nbsp;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Patrick&lt;/b&gt;: Backbone, very small, minimal. you don't bring too much dependencies. you can choose what you want.&amp;nbsp;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adam&lt;/b&gt;: Angular, Two-way data binding is the key feature. Synchronization of HTML and your JS. Choose framework with data-binding. Ember is essentially a language, forces its own object model. Backbone as well. Hexagonal or Angular is pure JS.Your application can live outside of Angular.&lt;b&gt;You could use Angular with a Hexagonal app. &lt;/b&gt;Backed by Google, more mature than Ember.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: Data binding is not as important as you may think. Manual control is not that difficult. Hexagonal doesn't have data binding jilt-in. Apps are not about data changes, but about actions&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Piotr&lt;/b&gt;: I agree that data binding is important. Both, Angular and Ember are good for big applications. Nested views, zombie views (backbone). Angular has its own compiler for DOM elements. You need to know how the compiler works. Angular uses dirty checking. Angular claims that your UI shouldn't have than 2000 elements. You're screwed if you have more.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Adam&lt;/b&gt;: We built a 100 rows, 500 columns table. We managed to do it with Angular. It's not that hard to do the UI part. Directives are like helpers for html.&amp;nbsp;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
22m6s&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Do you have to take the mindset of the creator?&lt;/b&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Adam&lt;/b&gt;: Most of the things in Angular are optional.If you don't use the HTML part, you lose a lot.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: It's a problem of all of us here, including Hexagonal. We use different terminology for different things. All the frameworks are far from being Rails, we're not mature enough. All the frameworks are in their infancy years.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Patrick&lt;/b&gt;: It's easy to work with Rails and Backbone&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Piotr&lt;/b&gt;: Ember has its own class model. It's done mainly for making it easy to optimise. Ember is about Convention over Congifuration. Rails in JS. Ember is like Rails, Backbone is like Sinatra. At some point you have to use more plugins if you start with something minimal. A lot of pain if you want to write a big app with a small framework.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: I disagree. I would use a framework for a prototype or for a small app. Once the app grows, it has its own world. I don't want the framework to go into my way. I want to have the control over the applications. I'd use Ember for smaller apps, not for bigger apps.&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;br /&gt;
27m23s&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;How to be involved in the community, how to learn the framework?&lt;/b&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;Adam&lt;/b&gt;: Angular has really good docs. All development happens on github.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Andrzej&lt;/b&gt;: Hexagonal has just started. It got the name just recently. We've used it for over a year. We have a strong team behind it. Our goal is to show the guidelines.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Piotr&lt;/b&gt;: Ember is 1.0RC now. Docs are better now. IRC is very active. Google Group.&lt;/div&gt;
&lt;div class="p3"&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Patrick&lt;/b&gt;: JavaScript and Ruby devs can help.&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;
&lt;b&gt;END&lt;/b&gt;&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;
If you're interested in Single Page Apps, you may want to &lt;a href="https://twitter.com/andrzejkrzywda"&gt;follow me on Twitter&lt;/a&gt;.&lt;/div&gt;
&lt;div class="p4"&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/6326759586549000062/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=6326759586549000062" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6326759586549000062?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6326759586549000062?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/04/single-page-applications-fight-video.html" title="Single Page Applications fight - video" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/h8XeZFW1Ad0/default.jpg" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DUQCQHw6eCp7ImA9WhBSFk4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5601020062389713935</id><published>2013-02-23T16:36:00.000Z</published><updated>2013-02-23T16:36:01.210Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-23T16:36:01.210Z</app:edited><title>Why do projects take so long?</title><content type="html">&lt;br /&gt;
Some projects take a long time to develop. In different contexts, the definition of "long" may vary. It was always interesting to me, what are the reasons for it. Recently, though, it became my obsession.&lt;br /&gt;
&lt;br /&gt;
I've started collecting some thoughts on this topic.&lt;br /&gt;
&lt;br /&gt;
Ask yourself and your teammates about the last project you've been working on. &lt;b&gt;"Would we be able to implement the same result in 1 month? In 1 week?"&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Surprisingly often, I'm answering to myself - yes, that would be possible, given some assumption. I've had similar answers from my colleagues.&lt;br /&gt;
&lt;br /&gt;
Where does it come from?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Is it the known tendency to underestimating a problem by developers?&lt;/b&gt; I don't think so, as we're talking about a project, that has already happened. We know what is to be done. We are aware of edge cases.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;"This is time it will be different, faster"&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is another popular trend among us, developers. Most of us are optimistic, even the experienced ones. It's not some kind of a student-syndrome (I'll do it tonight), but a well-thought statement. Is it really different and faster? Not always…&lt;br /&gt;
&lt;br /&gt;
Where does this optimism come from? Good developers become better at solving technical problems. With each problem solved, we know that we solved the problem forever. We love solving problems, every day we're smarter by this attitude. We're progressing and the optimism may come from that.&lt;br /&gt;
&lt;br /&gt;
It's almost impossible to get a second chance of working on the same project. What would that even mean from a business perspective? We rarely get that chance.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Is it the technology that let us think, that we could do better this time?&lt;/b&gt; That's a serious candidate. Every time, I switched to better technologies or to better architectures, I noticed the speed increase. I was more confident. I saw the results.&lt;br /&gt;
&lt;br /&gt;
I remember a situation, back in 2004/2005. I was involved in preparing an estimate for a new project. The estimate was about 6 months for 4 developers (assuming ASP.NET). Very shortly after that I learnt Rails. I realised, that the project is perfect for Rails. It was a CRUD-based web app. I kept convincing the management to give it a try. No luck. Finally, I had a chance of coding live in front of some managers. I implemented the main path in about 1 hour (I was well prepared). That convinced them. We've finished this project in 1.5 month, with one junior programmer and me being mostly a PM and a Rails mentor.&lt;br /&gt;
&lt;br /&gt;
What's the lesson? It's hard to tell. I'm not trying to say that only Rails was the reason. Motivation? The passion behind it? Trying to prove something? The focus? I think it was a combination of all of the above aspects.&lt;br /&gt;
&lt;br /&gt;
Is it easy to repeat those aspects? Do they sound familiar?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Have you ever attended a hackathon?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
There are many kinds of hackathons. What's most important in this context, is how much can be done in a very limited time. If you look at the results of Rails Rumble, some of the apps are quite big. Many features, everything is polished.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Hackathons are proves that we are able to develop apps quickly.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
How can we apply hackathon lessons to our every-day projects? Is it possible?&lt;br /&gt;
&lt;br /&gt;
What else can help us developing software faster?&lt;br /&gt;
&lt;br /&gt;
I would love to know your opinions.&lt;br /&gt;
&lt;br /&gt;
</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5601020062389713935/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5601020062389713935" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5601020062389713935?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5601020062389713935?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/02/why-do-projects-take-so-long.html" title="Why do projects take so long?" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;CU4CQ3szcCp7ImA9WhBSFkw.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-414543971189754046</id><published>2013-02-23T10:06:00.000Z</published><updated>2013-02-23T10:06:02.588Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-23T10:06:02.588Z</app:edited><title>Angular or Ember? Congratulations, you've already won.</title><content type="html">At the &lt;a href="http://wrocloverb.com/"&gt;wrocloverb&lt;/a&gt; conference we've decided to have a Single Page Applications "fight". (The format of fight worked pretty well last year for the JRuby vs Rubinius battle).&lt;br /&gt;
&lt;br /&gt;
We're having Ember, angular, Backbone and &lt;a href="http://hexagonaljs.com/"&gt;hexagonaljs&lt;/a&gt; representatives. As I'm representing the last one, during the last few days, I've did more research on the other alternatives.&lt;br /&gt;
&lt;br /&gt;
There are huge differences between all the choices. Some of the frameworks are like Rails, some are more like Sinatra. &lt;a href="http://andrzejonsoftware.blogspot.com/2013/02/non-framework-approach-to-javascript.html"&gt;Hexagonaljs is not even a framework&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I have been making notes on the differences, collected jokes on each of the opponents. It's going to be a great fight :)&lt;br /&gt;
&lt;br /&gt;
Anyway.&lt;br /&gt;
&lt;br /&gt;
I realised one thing. &lt;b&gt;If you're wondering which of the frameworks, non-frameworks to choose, you have already won&lt;/b&gt;. You are already in the world of Single Page Applications. There's no wrong choice in here. You will be fine with any of the frameworks.&lt;br /&gt;
&lt;br /&gt;
There's a warning, though. I know many people who entered this world and they don't want to come back to the non-SPA reality.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Congratulations, that was a good choice!&lt;/b&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/414543971189754046/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=414543971189754046" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/414543971189754046?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/414543971189754046?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/02/angular-or-ember-congratulations-youve.html" title="Angular or Ember? Congratulations, you've already won." /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;CUECQXc6eSp7ImA9WhBSFUk.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5272296027566600091</id><published>2013-02-22T14:09:00.001Z</published><updated>2013-02-22T14:34:20.911Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-22T14:34:20.911Z</app:edited><title>Non-framework approach to JavaScript apps - hexagonal.js</title><content type="html">This week we have officially launched and announced &lt;a href="http://hexagonaljs.com/"&gt;hexagonal.js&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The announcement was welcomed with a fair amount of interest. Jan Filipowski at the Arkency blog did a great job of &lt;a href="http://blog.arkency.com/2013/02/introducing-hexagonal-dot-js/"&gt;explaining the basic ideas&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
I'd like to cover the topic of hexagonaljs not being a framework.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What is a framework?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
Some time ago I asked "&lt;a href="http://andrzejonsoftware.blogspot.com/2012/12/what-is-framework.html"&gt;What is a framework?&lt;/a&gt;". I liked the following answer:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;span style="background-color: #f5ede4; font-family: Helvetica, Arial, Verdana, 'Trebuchet MS', sans-serif; font-size: 16px; line-height: 22.390625px;"&gt;In the case of a framework, your code is called by it. In the case of a library, your code call it. Rails is a framework, and provides libraries too.&lt;/span&gt;&lt;/blockquote&gt;
&lt;br /&gt;
I have a love/hate relationship with frameworks. That's why I struggled for months, what to do with the ideas that we're now calling hexagonal.js. I didn't want it to be a framework. That would ruin the whole experience.&lt;br /&gt;
&lt;br /&gt;
Let me tell you a story on how it all started and why we didn't want it to be a framework.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The technical story of haxagonal.js&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
The first ideas were created when we were working on social web games at GameBoxed. Given the scale we were operating on (sometimes 4-5 social apps/games a month) we needed a high degree of reusability. Reusability requires good modularity. Often, we've had apps that have the same "logic", but they had much different GUI, sounds, FB integration etc.&lt;br /&gt;
&lt;br /&gt;
We got the idea of use cases as objects from the DCI approach (DCI is much more than that!). We've experimented with the concept that it's the use-case that drives everything. Driving something (like playing sounds) meant calling it. Calling it directly meant creating a coupling between the use-case and the SoundAdapter, which didn't sound like a good idea.&lt;br /&gt;
&lt;br /&gt;
One approach was to use events. The use case would trigger an event and the adapter would bind to it. It resulted in less coupling. It wasn't bad. To me, it wasn't yet the final solution, though. I didn't like the fact, that the use-case objects were full of "trigger someEvent" statements.&lt;br /&gt;
&lt;br /&gt;
When I looked at the events, I&amp;nbsp;realised&amp;nbsp;that they happen usually at the beginning or at the end of a method in the use case.&lt;br /&gt;
&lt;br /&gt;
Before, After....&lt;br /&gt;
&lt;br /&gt;
Wait, wasn't that what AOP was about?&lt;br /&gt;
&lt;br /&gt;
Introducing some simple AOP techniques (thanks to awesome Raganwald's &lt;a href="https://github.com/raganwald/YouAreDaChef"&gt;library&lt;/a&gt;!), we have achieved exactly what was needed. This is what we currently call a Glue code. It's almost like a configuration, in most cases. No logic, just declarations.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Hexagonal architecture&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
We started with MVC in mind. The most basic rule of MVC is that when the model changes, the views are notified about it. After some time, we've realised that it's not only about views, unless you try to fit "playing sounds" into the View layer ;)&lt;br /&gt;
&lt;br /&gt;
In a hexagonal architecture, GUI is just one of the adapters. It's usually the most important one, but technically, still, just an adapter.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;In many apps, the GUI is the only adapter.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
ServerSideAdapter, PusherAdapter, SoundAdapter, FirebaseAdapter, FacebookAdapter, LinkedInAdapter - those are just examples of the adapters, that we used so far.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;It's not a framework&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
Given all of the above, we were struggling on how to bring this idea to people, without making them depend on any framework. The whole idea is a bit anti-framework.&lt;br /&gt;
&lt;br /&gt;
Hexagonal.js is not even a library. It's mostly an architectural style adapted to JavaScript apps. We provide many examples (and more in progress..), that can guide you. You can copy them, fork them and have a good starting point.&lt;br /&gt;
&lt;br /&gt;
It's probably a slightly unusual approach to deliver some ideas to you. It's not a framework, not a library.&lt;br /&gt;
&lt;br /&gt;
Hexagonal.js is a set of good patterns that are extracted from real-world production apps. It was used to build dozens of apps, with a good speed of development.&lt;br /&gt;
&lt;br /&gt;
You can look at &lt;a href="https://github.com/hexagonaljs"&gt;the examples we already have&lt;/a&gt;. Look at the use case object, the glue and the adapters. It's a pattern that reappears in every hexagonaljs app. There is also an example of using it from a Rails app.&lt;br /&gt;
&lt;br /&gt;
Tell us what you think about this approach. We've published it to bring more ideas. We're open for suggestions!&lt;br /&gt;
&lt;br /&gt;
Thanks for reading.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5272296027566600091/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5272296027566600091" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5272296027566600091?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5272296027566600091?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/02/non-framework-approach-to-javascript.html" title="Non-framework approach to JavaScript apps - hexagonal.js" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEAMRnY6cCp7ImA9WhBTGEg.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-4419417930189625324</id><published>2013-02-14T14:39:00.002Z</published><updated>2013-02-14T14:39:47.818Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-14T14:39:47.818Z</app:edited><title>Frontend first</title><content type="html">&lt;br /&gt;
Some time ago, I blogged about the different &lt;a href="http://andrzejonsoftware.blogspot.com/2012/06/from-backend-to-frontend-mental.html"&gt;phases of mental transition&lt;/a&gt; when working with JavaScript frontends. Here's the shorten version:&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;1. No-JavaScript phase&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. JQuery explosion&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Page and Widget objects&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Single Page Application&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Once you're in phase 4 and you create apps this way, you realize that you don't need the backend in order to create the Single Page App. Even more, you shouldn't start with a backend.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Frontend first&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is the additional phase. Frontend first. In most of the typical situations, it's much better to start with a Single Page Application and use LocalStorage or some kind of a InMemoryServerSideAdapter for the first phases of the development.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;Only after you know how the frontend works and what kind of server interaction it requires, it actually makes sense to start working on the backend.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
We've tried this approach in several Single Page Apps and it worked great for us. It now seems like the most natural way of working.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; to learn more about Single Page Applications.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/4419417930189625324/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=4419417930189625324" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/4419417930189625324?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/4419417930189625324?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2013/02/frontend-first.html" title="Frontend first" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total></entry><entry gd:etag="W/&quot;AkYMSHs7fip7ImA9WhNXGE0.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5716340885489752753</id><published>2012-12-06T15:36:00.001Z</published><updated>2012-12-06T15:36:29.506Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-06T15:36:29.506Z</app:edited><title>What is a framework?</title><content type="html">The title question made me struggle for months.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;What is a framework?&lt;/li&gt;
&lt;li&gt;What is the difference between a library and a framework?&lt;/li&gt;
&lt;li&gt;If I use a framework as a library, does it make it a library?&lt;/li&gt;
&lt;li&gt;Is Rails a framework?&lt;/li&gt;
&lt;li&gt;Is Backbone a framework?&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Can you help me with your answers?&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5716340885489752753/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5716340885489752753" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5716340885489752753?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5716340885489752753?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/12/what-is-framework.html" title="What is a framework?" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>12</thr:total></entry><entry gd:etag="W/&quot;CEANSHY7eSp7ImA9WhJVEU0.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-7991148976826542236</id><published>2012-08-27T21:26:00.000Z</published><updated>2012-08-27T21:26:39.801Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-27T21:26:39.801Z</app:edited><title>Rails legacy applications</title><content type="html">The topic of Rails legacy applications is becoming more popular recently.&lt;br /&gt;
&lt;br /&gt;
We, at &lt;a href="http://rails.arkency.com/"&gt;Arkency&lt;/a&gt;, sometimes receive questions whether we can take control over an existing application. It's never an easy decision.&lt;br /&gt;
&lt;br /&gt;
Legacy apps contain legacy bugs, which can quickly become "our" bugs. They often have no tests, or just failing tests. If you're very unlucky, you can find some really shitty code.&lt;br /&gt;
&lt;br /&gt;
What's the reward?&lt;br /&gt;
&lt;br /&gt;
This is a story of one such project. We can proudly say that we successfully fixed the mess, not only that, we also created some beauty on top of that.&lt;br /&gt;
&lt;br /&gt;
Let me just say that it was such a pleasant experience that we decided that &lt;a href="http://rails.arkency.com/"&gt;Arkency&lt;/a&gt; should do more such projects.&lt;br /&gt;
&lt;br /&gt;
Challenge accepted! We're looking for more such challenges, email&amp;nbsp;&lt;a href="mailto:andrzejkrzywda@gmail.com"&gt;me&lt;/a&gt; if you have an old Rails app that needs to be fixed.&lt;br /&gt;
&lt;br /&gt;
Read the slides of&amp;nbsp;&lt;a href="http://mlomnicki.com/"&gt;Michał Łomnicki&lt;/a&gt;&amp;nbsp;to learn the details.&lt;br /&gt;
&lt;br /&gt;
&lt;iframe allowfullscreen="allowfullscreen" frameborder="0" height="356" marginheight="0" marginwidth="0" scrolling="no" src="http://www.slideshare.net/slideshow/embed_code/14026324" style="border-width: 1px 1px 0; border: 1px solid #CCC; margin-bottom: 5px;" width="427"&gt; &lt;/iframe&gt; &lt;br /&gt;
&lt;div style="margin-bottom: 5px;"&gt;
&lt;strong&gt; &lt;a href="http://www.slideshare.net/Michaomnicki/having-fun-with-legacy-apps" target="_blank" title="Having fun with legacy apps"&gt;Having fun with legacy apps&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href="http://www.slideshare.net/Michaomnicki" target="_blank"&gt;Michał Łomnicki&lt;/a&gt;&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
Thanks to &lt;a href="http://mlomnicki.com/"&gt;Michał&lt;/a&gt; and &lt;a href="http://mostlyobvio.us/"&gt;Paweł Pacana&lt;/a&gt; for the awesome work!&lt;br /&gt;
&lt;br /&gt;
Let me know if you want to learn more about what we did and I will convince Michal to blog about it :)&lt;/div&gt;
</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/7991148976826542236/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=7991148976826542236" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/7991148976826542236?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/7991148976826542236?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/08/rails-legacy-applications.html" title="Rails legacy applications" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;A0MCRncycSp7ImA9WhJWGUQ.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-3477055664348445700</id><published>2012-08-26T16:44:00.002Z</published><updated>2012-08-26T16:44:27.999Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-26T16:44:27.999Z</app:edited><title>Is CoffeeScript better than Ruby?</title><content type="html">If you are subscribed to our &lt;a href="http://rails.arkency.com/newsletter"&gt;Arkency newsletter&lt;/a&gt;&amp;nbsp;(we send an email every week or two with some interesting links and our comments), you probably noticed that there is an ongoing debate in our team - whether CoffeeScript (actually JS) has a good standard library.&lt;br /&gt;
&lt;br /&gt;
I have recently watched &lt;a href="http://www.youtube.com/watch?v=FkLVl3gpJP4#t=33m30s"&gt;an interview with DHH&lt;/a&gt; about his opinions on Single Page Applications.&lt;br /&gt;
&lt;br /&gt;
DHH was explaining why they don't go the SPA way with their new 37Signals applications. They chose to generate JS and HTML on the backend and send it back to the client.&lt;br /&gt;
&lt;br /&gt;
One of the DHH's arguments was that they prefer the Ruby stack (with Rails) than the experience of writing CoffeeScript application, with the server being just for JSON API.&lt;br /&gt;
&lt;br /&gt;
Overall, I think that DHH makes some good points, but &lt;b&gt;I don't agree with the assumption that it's better to work with the Ruby stack than with CoffeeScript&lt;/b&gt;. Sure, the patterns are not so mature as with a typical Rails app, so sometimes it takes more time to do the same thing, however their approach of sending JS is also not the most trivial one and it creates a complex architecture, IMO.&lt;br /&gt;
&lt;br /&gt;
First,&lt;b&gt; the syntax of CoffeeScript is better &lt;/b&gt;to me, than the Ruby syntax. This is subjective and I'm not expecting everyone to agree. To me, it's enough that the code is mostly shorter while still very elegant.&lt;br /&gt;
&lt;br /&gt;
Second, the libraries. Yes, &lt;b&gt;JS stdlib is almost non-existing&lt;/b&gt;. It's almost always better to avoid the existing stdlib and rely on sugarjs or underscore. Ruby is winning here. Now. With the growing JavaScript communities, we'll see a huge improvements very soon. The &lt;a href="http://sugarjs.com/"&gt;sugarjs&lt;/a&gt; library is already awesome and I don't feel I'm sacrificing anything by using it, compared to the Ruby libs.&lt;br /&gt;
&lt;br /&gt;
You can improve the libraries, but it's hard to improve the syntax.&lt;br /&gt;
&lt;br /&gt;
I may agree with DHH, that the SPA environment is not yet at the same level as Rails is now. Even DHH says that the situation happening with JS MVC is a huge shift. In my opinion (and &lt;a href="http://mlomnicki.com/javascript/2012/08/13/from-backend-to-frontend.html"&gt;not only mine&lt;/a&gt;), &lt;b&gt;we see a revolution that can be only compared to Rails in 2004-2005&lt;/b&gt;. Back then, Rails also wasn't that mature, but we were able to use it and have a really well working applications (my first production Rails app was released in April 2005 and was used by hundreds of users every day).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Back to the title dilemma. Is CoffeeScript better than Ruby?&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
We need them both. The trend of SPA will be growing and we can't use Ruby there. On the other hand, it's not easy to use CoffeeScript on the backend (nodejs based solutions are nowhere near the stability of Ruby solutions) and Ruby is a great choice in there. In most of the apps that I'm currently working on, &lt;b&gt;I spend like 80% of my time with CoffeeScript on the frontend and 20% on Ruby on the backend&lt;/b&gt;. That's my answer :)&lt;br /&gt;
&lt;br /&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/3477055664348445700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=3477055664348445700" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3477055664348445700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3477055664348445700?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/08/is-coffeescript-better-than-ruby.html" title="Is CoffeeScript better than Ruby?" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total></entry><entry gd:etag="W/&quot;DkUHQ348fip7ImA9WhJRE0Q.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-2686946783241473900</id><published>2012-07-15T23:17:00.000Z</published><updated>2012-07-15T23:17:12.076Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-15T23:17:12.076Z</app:edited><title>JS frontends are like desktop apps</title><content type="html">I noticed a trend recently, among developers, that we need to learn how to work with JS frontends. Obviously, it's great that people want to improve their skills, but is it really something new that we need to learn?&lt;br /&gt;
&lt;br /&gt;
I suppose, that many of us at some point have been working on a desktop application. Was it a Java Swing app or a .NET Windows Forms or maybe Delphi app, doesn't matter that much.&lt;br /&gt;
&lt;br /&gt;
What's important is that &lt;b&gt;a JS frontend is very similar to a desktop applications&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Yes, they are not completely the same, we can do a few things that are easier in the browser than on the desktop app. Those differences don't influence the way we architecture the JS apps.&lt;br /&gt;
&lt;br /&gt;
If you haven't had a chance to work on a desktop app then you're missing a lot, but still, it's much better to read about the desktop patterns, than to try the new shiny JS framework.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/2686946783241473900/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=2686946783241473900" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/2686946783241473900?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/2686946783241473900?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/07/js-frontends-are-like-desktop-apps.html" title="JS frontends are like desktop apps" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;D08FQXczeSp7ImA9WhJTFkg.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5897846011396552557</id><published>2012-06-25T20:23:00.001Z</published><updated>2012-06-25T20:23:30.981Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T20:23:30.981Z</app:edited><title>From backend to frontend - the mental transition</title><content type="html">Recently I blogged about my thoughts on the idea that&lt;a href="http://andrzejonsoftware.blogspot.com/2012/06/frontend-is-separate-application.html"&gt;&amp;nbsp;frontends are in fact separate applications&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Today, I'd like to describe the transition of my mental model in thinking about views and frontends.&lt;br /&gt;
&lt;br /&gt;
I thought that it was only me who went that path, but this excellent &lt;a href="https://speakerdeck.com/u/sarahmei/p/backbonejs-basics-beyond"&gt;Backbone introduction&amp;nbsp;slide deck&lt;/a&gt;&amp;nbsp;helped me realize that it's a common process for backend developers.&lt;br /&gt;
&lt;br /&gt;
This process consists of the following steps:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. No-JavaScript phase&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
No JavaScript at all, or using it through some kind of backend plugins (like the ones Rails gives - link_to_remote etc.)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. JQuery explosion&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This happens when you use straight JQuery, there is lots of JQuery plugins updating different views, replacing html and using some simple Ajax.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Page and Widget objects&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
It's basically the same as phase 2, but this time you wrap all the JS code into nice objects/classes, so that you start unit-testing them. You also start packaging them as "pages, "widgets" or "components". You're still rendering the html on the server side and the data is either in the html or in some pre-rendered JavaScript files. You're switching to CoffeeScript. This phase can be "fine" for many applications.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Single Page Application&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Single page application is the phase in which you move all of the html generation from the server to the client. There are no full page reloads. Of course, there might be phases between 3 and 4, where some of your html is rendered here, some is rendered there. Luckily, you prefer consistent solutions, so you end up quickly in phase 4.&lt;br /&gt;
It's this phase where you think about the frontend as a separate application. All the data you get, come from API requests. You know the difference between MVC here and Model2 on the backend. You explore the different techniques for designing the domain - gui communication.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Any other phase?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
In the Sarah's slides you will also find a next phase here - Frameworks. I'm not putting it here, as I think we choose frameworks too early. It's a topic for another blog post.&lt;br /&gt;
&lt;br /&gt;
I'm in the 4th phase for quite a while now and I don't feel any need of a framework.&lt;br /&gt;
&lt;br /&gt;
There's also an interesting area to explore, where you have several mini-application in your web app.&lt;br /&gt;
&lt;br /&gt;
In my next blog posts I'm going to help you learn how to solve typical frontend problems without using a full framework.&lt;br /&gt;
&lt;br /&gt;
Just to be clear, I'm fine with Backbone or AngularJS or others. It's just that I think, that those frameworks can be limiting to our projects very early on.&lt;br /&gt;
&lt;br /&gt;
Which phase are you in?&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5897846011396552557/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5897846011396552557" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5897846011396552557?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5897846011396552557?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/06/from-backend-to-frontend-mental.html" title="From backend to frontend - the mental transition" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>6</thr:total></entry><entry gd:etag="W/&quot;C0cFSHs4eCp7ImA9WhJTFks.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5074141035314992153</id><published>2012-06-24T11:44:00.000Z</published><updated>2012-06-25T21:50:19.530Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T21:50:19.530Z</app:edited><title>Frontend is a separate application</title><content type="html">Despite my experience with working on desktop applications, &lt;b&gt;I've been avoiding any frontend (here meaning JavaScript/html) for years&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
It wasn't because I didn't know JavaScript, it's just that I am a developer who cares about code quality and JavaScript coding was far from any "quality" areas (in my mind).&lt;br /&gt;
&lt;br /&gt;
I felt safe with programming backends and I was more than happy with Rails. Rails is a framework that is really good at abstracting the frontend problems. It gives you a set of view helpers, so that you can do almost everything in Ruby.&lt;br /&gt;
&lt;br /&gt;
Whenever I had a project that involved more JavaScript (because the UX designer required it) it was a painful experience to me. I just couldn't find a good way of structuring the JS code. I didn't know how to test it well (and yes, I knew Selenium, thank you).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Now I love working on frontends.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Why the change?&lt;br /&gt;
&lt;br /&gt;
I realized that my mental model of a web applications, that I had in my mind, was wrong. I'm guilty of not thinking it through harder in the past. The Rails framework created an illusion for me that the frontend is the View part of the MVC architecture. It's not and &lt;a href="http://andrzejonsoftware.blogspot.com/2011/09/rails-is-not-mvc.html"&gt;Rails is not MVC.&lt;/a&gt;&amp;nbsp;It's not only a Rails problem, I think that in most web frameworks we see a similar illusion.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The View part is another application&lt;/b&gt;, that Rails happens to generate quite nicely.&lt;br /&gt;
&lt;br /&gt;
The mental process of moving the View from the backend app to a separate application is quite interesting and I hope to cover it another blog post if anyone is interested [UPDATE: &lt;a href="http://andrzejonsoftware.blogspot.com/2012/06/from-backend-to-frontend-mental.html"&gt;I blogged about this process&lt;/a&gt;]. I see a similar pattern of transition among my fellow developers.&lt;br /&gt;
&lt;br /&gt;
Once I realized that the JS is in fact another application it was like a whole new world of programming opened to me. With the rise of CoffeeScript it became even more cool. I'm able to use all the patterns from my desktop apps experience (I've been working a lot with Java/Swing apps and on an .NET Windows Forms app with IronPython).&lt;br /&gt;
&lt;br /&gt;
A CoffeeScript (or JS) application can embrace the original vision of MVC. There are new&amp;nbsp;architectural&amp;nbsp;patterns like DCI, which put use cases in front of everything, that fit perfectly well into this kind of apps. There are some concepts from AOP that come back (even Twitter uses them) and are great for domain - gui separation.&lt;br /&gt;
&lt;br /&gt;
Even more, the backend is now an optional part (a plugin) of my project, it's possible to run the frontend application without a Rails backend.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;We live in exciting times. The Single Page Applications are becoming more and more popular. I'm no longer a backend-only programmer and I am very happy with that!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5074141035314992153/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5074141035314992153" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5074141035314992153?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5074141035314992153?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/06/frontend-is-separate-application.html" title="Frontend is a separate application" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>16</thr:total></entry><entry gd:etag="W/&quot;Dk8ERHs9eSp7ImA9WhVaEU0.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-1312943467316590275</id><published>2012-06-07T21:33:00.000Z</published><updated>2012-06-07T21:33:25.561Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-07T21:33:25.561Z</app:edited><title>How to waste time on TDD</title><content type="html">This blog post was &lt;a href="http://thesingularity.pl/blog/2012/jak-stracic-czas-na-tdd-i-nie-dostarczyc-na-czas/"&gt;originally written&lt;/a&gt; by Piotr Włodarek on his &lt;a href="http://thesingularity.pl/"&gt;TheSingularity.pl&lt;/a&gt; blog. I liked it so much that I translated it to English, so that it can reach a broader audience.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;Some people argue that TDD slows down the development process. If you want to follow this opinion here's what you should do:&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Write tests after writing the production code.&lt;/li&gt;
&lt;li&gt;Waste no time thinking about designing, simply jump straight into the TDD loop and do 100% of the design work there. You'll have a chance to change your code and tests structure over and over again.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Learn how to write test scenarios completely on your own, don't bother watching any screencasts and don't read any books on the topic.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Make sure your tests load at least half a minute before they actually start testing anything. You can easily achieve that by loading the whole framework and working with your old crappy HDD.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Make sure all the features are tested through the GUI (by driving a web browser or desktop GUI window).&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Make sure all your tests depend on the database.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Manually find the corresponding test file and the production code.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Navigate between desktops, windows, tabs only to find the tests starting script.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Try to write as few classes as possible to ensure every class has multiple unrelated responsibilities. These are guaranteed to be a testing nightmare.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Write beautiful step definitions in Cucumber even if your customer doesn't care about reading your specs (or perhaps you don't even have a customer yet).&lt;/li&gt;
&lt;/ol&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/1312943467316590275/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=1312943467316590275" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1312943467316590275?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1312943467316590275?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/06/how-to-waste-time-on-tdd.html" title="How to waste time on TDD" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;CEcGSHk5eCp7ImA9WhJTFk4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-1051061467427480006</id><published>2012-05-29T10:37:00.002Z</published><updated>2012-06-25T13:47:09.720Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T13:47:09.720Z</app:edited><title>account.transfer(..) - is it good OOP?</title><content type="html">There is this famous example, that you can find in almost every OOP-related book:&lt;br /&gt;
&lt;br /&gt;
Let's say that account is an object, and you have:&lt;br /&gt;
&lt;br /&gt;
account.transfer(200, target_account)&lt;br /&gt;
&lt;br /&gt;
For some time now, I've had issues with this example.&lt;br /&gt;
&lt;br /&gt;
I&lt;b&gt;s it really a responsibility of the account object to transfer money to another account?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Is it not one of the responsibilities of the Bank object? It just feels weird that an account knows how to do the proper stuff about the complicated transferring use case.&lt;br /&gt;
&lt;br /&gt;
The topic of DCI is really popular recently, which is cool, as it's a very fresh approach to object oriented architectures. The .transfer example in DCI is usually implemented as injecting the SourceAccount and TargetAccount roles to the basic account objects. We change the implementation, but the effect is the same - the account object has the knowledge about the transfer stuff.&lt;br /&gt;
&lt;br /&gt;
Wouldn't it be better if we have this as a responsibility of the Bank object? It could work as a use case or as a role, but both fit better in the bank, in my opinion.&lt;br /&gt;
&lt;br /&gt;
What do you think?

&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/1051061467427480006/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=1051061467427480006" title="17 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1051061467427480006?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1051061467427480006?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/05/accounttransfer-is-it-good-oop.html" title="account.transfer(..) - is it good OOP?" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>17</thr:total></entry><entry gd:etag="W/&quot;D0YGSHo4eip7ImA9WhVRGU4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-2539953078479146600</id><published>2012-03-28T11:45:00.000Z</published><updated>2012-03-28T11:45:29.432Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-03-28T11:45:29.432Z</app:edited><title>Remote company - my talk at the 4developers conference</title><content type="html">Remote work and remote collaboration are topics that I have experience with for 5 years now.&lt;br /&gt;
&lt;br /&gt;
During that time I started &lt;a href="http://rails.arkency.com/"&gt;Arkency&lt;/a&gt;, the Ruby consulting company that I'm really proud of. There are now 9 Ruby experts in the team and most of the time we collaborate remotely, even though most of us are based in the same city (the&amp;nbsp;beautiful&amp;nbsp;Wrocław, Poland) where we have an office.&lt;br /&gt;
&lt;br /&gt;
Together with my business partners I also started &lt;a href="http://gameboxed.com/"&gt;GameBoxed&lt;/a&gt;, a company focused on building and selling social games for brands. There are 6 developers in the IT team, but here we also have sales, marketing, design and support teams. Most of the collaboration is done remotely, even though we do have offices in Wrocław and in Warsaw.&lt;br /&gt;
&lt;br /&gt;
Remote collaboration is not a piece of cake. We made some mistakes along the way and we learnt our lessons. There are however huge gains in this way of working, if it's done right.&lt;br /&gt;
&lt;br /&gt;
I want to share the lessons with you. I will be speaking about this topic at the &lt;a href="http://4developers.org.pl/"&gt;4developers conference&lt;/a&gt; in Poznan, 17-18 April.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/2539953078479146600/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=2539953078479146600" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/2539953078479146600?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/2539953078479146600?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/03/remote-company-my-talk-at-4developers.html" title="Remote company - my talk at the 4developers conference" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;C04BQngyeyp7ImA9WhRaFEU.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-1059069283252553014</id><published>2012-02-17T00:23:00.003Z</published><updated>2012-02-17T12:32:33.693Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-17T12:32:33.693Z</app:edited><title>How we ended up organizing a Ruby conference</title><content type="html">&lt;br /&gt;
&lt;b&gt;It started with a Ruby User Group in Wrocław&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It all started with the DRUG meetups. DRUG is a local Ruby user group in Wrocław. As the natural WRUG name was taken by our friends from Warsaw, we have decided to go with D as Dolny Slask, our region in Poland. That's how the awesome name was chosen :)&lt;br /&gt;
&lt;br /&gt;
We gathered together for more than 2 years now. At the start there were about 10 people coming every month. Now it's closer to 20.&lt;br /&gt;
&lt;br /&gt;
The interesting fact about our meetup is that &lt;b&gt;we almost always have like 5-6 talks submitted&lt;/b&gt;. Compared to meetups which end up with 1 talk that's quite a difference.&lt;br /&gt;
&lt;br /&gt;
We like to call DRUG a 'conference every month'.&lt;br /&gt;
&lt;br /&gt;
We love sharing opinions and discussions, so we started inviting people from other cities.&lt;br /&gt;
We've had guests from Krakow, Silesia, Kopenhagen, Cologne and many other places, we've visited Silesia, Poznan, Trojmiasto, Krakow.&lt;br /&gt;
&lt;br /&gt;
Apart from DRUG meetups there are also &lt;b&gt;DRUG dinners&lt;/b&gt;, events at which we just drink beer and discuss, no presentations.&lt;br /&gt;
&lt;br /&gt;
There are also regular &lt;b&gt;DRUG hackathons &lt;/b&gt;during which we develop quite a lot of interesting libraries. Bbq and Exceptioner are the ones we're most proud of.&lt;br /&gt;
&lt;br /&gt;
Every day, during our work we like to discuss recent Ruby stuff in the &lt;b&gt;#drug.pl irc channel&lt;/b&gt; (freenode).&lt;br /&gt;
&lt;br /&gt;
At some point it was getting quite clear where it's all going to.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;We want to organize a conference!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Once the idea came up about a year ago, I don't think there was any discussion if we want to do it. The focus was on "how". Everyone was very excited and the core organizing team set up very quickly.&lt;br /&gt;
&lt;br /&gt;
At first, we decided on the name, date and the venue.&lt;br /&gt;
&lt;br /&gt;
We did a lot of research on what was good/bad on other conferences like Euruko, RuPy, RubyConf etc.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The spirit.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The decision needed to be made if we want to be similar to other conference or shall we go another route.&lt;br /&gt;
&lt;br /&gt;
At some point it was clear that the spirit of our DRUG meetups should shape up the conference. &lt;b&gt;We want it to be about discussions as much as possible&lt;/b&gt;. We want it to be about how to make the Ruby world even better than it is.&lt;br /&gt;
&lt;br /&gt;
The idea of fights came up pretty quickly and we're very happy that we kept insisting on it. That's the main conference idea - let's confront different ideas on stage. Let's make it a major part of our conference.&lt;br /&gt;
&lt;br /&gt;
I'm happy to announce the main fights of our conference:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fight 1 - Rails and OOP&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This is all about the recent OOP movements in the Rails world. There are quite a few problems that people focus on and quite a few proposed solutions. We want to cover topics like:&lt;br /&gt;
&lt;br /&gt;
Persistence and domain logic separation&lt;br /&gt;
DCI&lt;br /&gt;
Backend/frontend separation.&lt;br /&gt;
Objects on Rails&lt;br /&gt;
TDD&lt;br /&gt;
@unclebob ideas - Rails is not your app.&lt;br /&gt;
&lt;br /&gt;
I'm really excited about this "fight". I'm going to blog about this fight more, so stay tuned.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Fight 2 - JRuby vs Rubinius&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Which one is better?&lt;br /&gt;
Which has the better "support"?&lt;br /&gt;
We invited people from both worlds, so the discussion will be of good quality.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Fight 3 - Testing&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Shall we keep loving/hating Cucumber?&lt;br /&gt;
What about the new tools, like bbq?&lt;br /&gt;
Object oriented acceptance testing?&lt;br /&gt;
Stubbing or mocking?&lt;br /&gt;
TDD - does it make sense?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Agenda and speakers&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
We didn't just want to invite random famous names from the community. We were focusing on people that fit well with the spirit of our conference. Every talk was carefully chosen. The choice was very difficult as we've had many talks submitted.&lt;br /&gt;
&lt;br /&gt;
What we ended up with is the best Ruby conference agenda I have ever seen. Really.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;There's a mission in this conference&lt;/b&gt;. We have strong opinions on how some of the Ruby/Rails issues need to be solved. We chosen speakers that are known of their quality and of their strong opinions. We have invited people known of their passion.&lt;br /&gt;
&lt;br /&gt;
Let's have a quick look at some of them:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Apotonick&lt;/b&gt; is famous for his REST passion and monolithic apps hate. We share many of his opinions and he is a perfect fit for our conference (also for the parties in the evenings :) ).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Avdi Grimm&lt;/b&gt; is the author of the "Objects on Rails" book. This topic makes an important part of our conference.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Steve Klabnik&lt;/b&gt; knows a lot about REST and creating API, we're really excited to have him speak on this topic.&lt;br /&gt;
&lt;br /&gt;
The idea of the real DataMapper library that comes with the DataMapper 2 sounds really cool to us and we have &lt;b&gt;Piotr Solnica&lt;/b&gt;, its author talking about it.&lt;br /&gt;
&lt;br /&gt;
We have &lt;b&gt;Drogus&lt;/b&gt; (Piotr Sarnacki), the Rails commiter, the author of Rails engines.&lt;br /&gt;
&lt;br /&gt;
We believe in distributed apps as the solution to monolithic problems with typical Rails apps. That's why we invited the author of 0MQ -&amp;nbsp; &lt;b&gt;Martin Sústrik&lt;/b&gt;. There's also &lt;b&gt;Florian Gilcher&lt;/b&gt; talking about "the fear of processes". &lt;b&gt;Krzysztof Kowalik&lt;/b&gt; is going to talk about his lessons learnt from the world of distributed apps.&lt;br /&gt;
&lt;br /&gt;
An important track of our conference is the "frontend apps" track. We have &lt;b&gt;Roy Tomeij &lt;/b&gt;speaking about creating reusable frontends with CoffeeScript, sass etc.&lt;br /&gt;
&lt;br /&gt;
We have only one talk about testing, but it will be delivered by &lt;b&gt;Michał Czyż&lt;/b&gt;, a developer whom I consider an expert in the topic of acceptance testing. I'm looking forward to his talk.&lt;br /&gt;
&lt;br /&gt;
There's also an original talk planned by Michał Taszycki, "the programmer workout".&lt;br /&gt;
&lt;br /&gt;
There's more to it, so just look at the official agenda.&lt;br /&gt;
&lt;br /&gt;
Don't forget that we have an open space planned, so more talk ideas may come up later :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Do you want to be part of it?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's going to be a historical event. You don't want to miss it. 5 years from now people will mention the wroc_love.rb 2012 as the breaking moment for the Ruby/Rails community. Watch it live :)&lt;br /&gt;
&lt;br /&gt;
Although the conference didn't start yet, we already know that the &lt;b&gt;wroc_love.rb 2013 is going to happen as well!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
For now, let's focus on this year event. It's only 4 weeks from now, March 10-11.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.eventbrite.com/event/2726199135"&gt;Make sure you have the ticket&lt;/a&gt;, book the hotel and travel. Invite your friends.&lt;br /&gt;
&lt;br /&gt;
Check out the conference &lt;a href="http://wrocloverb.com/"&gt;website&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
It's a community-organized conference. Non-profit. Be part of this community.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Let's make it awesome.&lt;/b&gt; Thanks!&lt;br /&gt;
&lt;br /&gt;
BTW, Wrocław is one of the nicest cities in the world, ask anyone who has been here.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/1059069283252553014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=1059069283252553014" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1059069283252553014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/1059069283252553014?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/02/how-we-ended-up-organizing-ruby.html" title="How we ended up organizing a Ruby conference" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total></entry><entry gd:etag="W/&quot;A0UBQHc6fip7ImA9WhRWFEk.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-7940958876977486693</id><published>2012-01-01T19:51:00.001Z</published><updated>2012-01-01T20:20:51.916Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-01T20:20:51.916Z</app:edited><title>DCI and Rails, lessons learnt</title><content type="html">&lt;div&gt;
I first learnt about &lt;a href="http://andrzejonsoftware.blogspot.com/2011/02/dci-and-rails.html"&gt;DCI&lt;/a&gt; almost one year ago. After some research and experiments, we decided to try it in production projects. Mostly in the &lt;a href="http://gameboxed.com/"&gt;GameBoxed&lt;/a&gt; project.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;My overall summary is that DCI is really awesome.&lt;/b&gt;&amp;nbsp;It simplifies the way you think about architectures. &amp;nbsp;Keep in mind, that our research is still in progress, it's not always clear what's the best solution.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
At GameBoxed we have one backend application (API) that runs many social games (CoffeeScript frontend applications). Each game can be different, but they share some common things together. The base object/class is a Player. In every game, though, the player can have different behavior. At the controllers level we have a filter that does the main specific-to-game extension, like:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;current_player.extend(ItemCollecting::Player)&amp;nbsp;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
or&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;i&gt;current_player.extend(Monopoly::Player)&amp;nbsp;&lt;/i&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
I'm not saying that this is hugely better than using inheritance, but for me it's a "lighter" way of object design. We can now test Monopoly::Player totally on its own, without all the base player responsibilities.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
At the level of the CoffeeScript applications we also use some DCI ideas, like constructing habits and use-cases (invite-friends, start-game, choose-prize). We're still in the process of finding the best design, but in my opinion the DCI way of thinking really helps in designing all of that.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;DCI reduces the number of objects in your project&lt;/b&gt;, but increases the number of roles they play. For me, it's easier to understand and think this way. In our case (the social games) the main objects interacting with each other are: Player, Game, Prize, Friends. Many other things *could* be a role (it doesn't have to). In the monopoly game, the Board can just be a role of the game object.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
The idea of use-cases, habits (as explained in the "Lean architecture" book), can make your architecture more explicit.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
It's not only roses, though. Here are some problems and my comments about the problems.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
1. &lt;b&gt;If not all of your team is truly convinced to DCI, then don't start with that&lt;/b&gt;. Even if only one person in a team doesn't get DCI it can make it very hard. As with every "new" thing, it requires more education. Experiments are fine, but at some point the whole team needs to have a common "mental model" of the system you're working on.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
2. &lt;b&gt;Using DCI at the level of ActiveRecord classes is wrong.&lt;/b&gt; We felt into this trap. DCI makes more sense at the OOP level. That's why I'm focusing so much about separating the two. One problem we've had was that, even though we extended some objects in "contexts", the same objects retrieved from AR again (without Identity Map) didn't have the roles. Thus the need for extending them again, deep in the models.&lt;br /&gt;
&lt;br /&gt;
3. &lt;b&gt;Extending objects with roles should be at the context level.&lt;/b&gt; We've had some extending at the model level (due to the lack of IdentityMap in Rails 3.0, now that we've upgraded to Rails 3.1 this problem disappears). This quickly leads to a mess. It's also a problem of using ActiveRecord "objects" with DCI. Use ActiveRecord only for persistence, not for domain logic.&lt;br /&gt;
&lt;br /&gt;
4. &lt;b&gt;DCI without contexts/use-cases is useless.&lt;/b&gt; We were not disciplined enough to have contexts everywhere and problems appeared quickly. I need to stress it more - &lt;b&gt;DCI is not (only) about dynamically extended objects&lt;/b&gt;. It's much more than that. You need to start thinking in use cases.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Let me know if you're interested in other lessons from using DCI.&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/7940958876977486693/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=7940958876977486693" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/7940958876977486693?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/7940958876977486693?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2012/01/dci-and-rails-lessons-learnt.html" title="DCI and Rails, lessons learnt" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total></entry><entry gd:etag="W/&quot;CEcCQHw8cSp7ImA9WhJTFk4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5547140810240599830</id><published>2011-12-30T21:45:00.000Z</published><updated>2012-06-25T13:47:41.279Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T13:47:41.279Z</app:edited><title>Rails is still cool</title><content type="html">There are many discussions recently on things that suck in Rails. Specifically, it's about how people misuse Rails. I think we need more OOP in Rails.&lt;br /&gt;
&lt;br /&gt;
Let me explain.&lt;br /&gt;
&lt;br /&gt;
Disclaimer: I started using Rails in 2004, now I run a &lt;a href="http://rails.arkency.com/"&gt;Rails consultancy&lt;/a&gt; and I've been more or less involved in about 30-35 Rails projects. I'm also involved in building a"social games for brands" product called &lt;a href="http://gameboxed.com/"&gt;GameBoxed&lt;/a&gt;, which proudly runs Rails 3.1 under the hood.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rails history and background&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
When Rails was released in 2004, I don't remember that DHH was saying it was perfect for everything. He showed us Rails and said: "look, this solves many problems of a typical web app". He was right. Somehow, it was assumed that the Rails way is the only way. This led to some people complaining about how Rails doesn't fit well into their more complex apps - I was one of such complainers, shame on me.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Rails is awesome for starting an app&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Let me repeat - Rails is great for starting an app. Do we want it or not (I want) we will see new Rails apps being created every day. The mainstream future is still before Rails, because it's really easy to start and new people will keep coming in.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why do you complain about Rails?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
It's not complaining about Rails, it's complaining about the current "best practices" and how we (me included) use Rails. In every project I worked on, &lt;b&gt;choosing Rails as the platform was a good decision&lt;/b&gt; at the beginning. It's just that at some point we not always realized that we should find our way, not the Rails way to implement the requirements. We had a hammer, so we looked for nails everywhere. It doesn't mean that we should drop Rails.&lt;b&gt; Projects evolve&lt;/b&gt;. What starts as a typical Rails app, evolves into something bigger, more complex at some point. Maybe it should be 5 small Rails apps cooperating together with some APIs?&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Why don't you write your own framework?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Someone asked me this question recently and I realized that my Rails critics is presented in a way that put Rails in a bad light. It's not true. &lt;b&gt;Rails is awesome. It has almost everything right.&lt;/b&gt; I don't want to create a new framework. It's too much work and there's no point in it. What I want, though, is looking for ways how to improve the apps that were misusing Rails at some point. In our company we sometimes inherit projects from other teams and that's my main area of research - how to maintain and refresh legacy Rails projects.&lt;br /&gt;
Another argument is that I haven't seen such an awesome community anywhere else. It's a community extremely open for new, good suggestions.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;But you criticized ActiveRecord so often, what about that?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
ActiveRecord is a great persistence layer. It was never my&amp;nbsp;favorite&amp;nbsp;part of Rails, because I never really liked the persistence part of projects. It's kind of an implementation detail to me.&lt;br /&gt;
Somehow, I misused Rails in this area. Instead of treating ActiveRecord as a persistence layer I started treating it as a domain layer as well. It was so tempting to do so...&lt;br /&gt;
Actually, at the beginning of a project it can be fine, to make AR you domain layer as well. Just for quick prototyping. But later I think that you should have a separate OOP domain model. I will come back to this point.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;ActionController is the problem&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
There's a valid argument that &lt;a href="http://blog.steveklabnik.com/posts/2011-12-30-active-record-considered-harmful"&gt;Steve Klabnik&lt;/a&gt; and others talk about. The way Rails handles the communication between controllers and views by default is awful. I suppose you all know what I mean. Note that Rails doesn't force you to use it this way. You're free to make it better. My suggestion? Use cells and research the presenter-based gems for views.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;ActionView is the problem&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
The problem is not ActionView itself, it's how some people misuse it. Rails community does a lot to discourage putting logic inside views and I think it goes well. We could go with Mustache or other logic-less templating systems, but it's assuming that we can't trust programmers. Welcome back to Java? BTW, &lt;a href="http://andrzejonsoftware.blogspot.com/2011/07/stop-hating-java.html"&gt;stop hating Java&lt;/a&gt; ;)&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;MVC is the problem&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
First of all, &lt;a href="http://andrzejonsoftware.blogspot.com/2011/09/rails-is-not-mvc.html"&gt;Rails is not MVC&lt;/a&gt;. Second, the Rails MVC (Model2) is fine for monolithic apps that are (yay!) going to the past. The future is in viewless, API-based backends with rich clients like mobile apps and CoffeeScript apps.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Rails for bigger apps&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
The first thing to remember is that &lt;a href="http://blog.firsthand.ca/2011/10/rails-is-not-your-application.html"&gt;Rails is not your application&lt;/a&gt;. Rails helps you as a delivery mechanism. Once it's bigger, you should consider:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;breaking from the monolith application into backend+frontend&lt;/li&gt;
&lt;li&gt;implement a separate (from AR) domain layer&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
It all assumes that you have tests for your project. If not, then you're screwed anyway. There's no chance for refactoring if you don't have tests.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Future?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
I see the future in separating backends from frontends. This alone makes the architectures simpler and easier to maintain.&lt;br /&gt;
Extract your domain layer. It's something that I'm experimenting with. It's hard, but it's not about Rails making it hard. Surprisingly it's hard because of the way we deploy Rails apps.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Domain layer&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
The point in separating the domain layer is that we want to implement some classes that have nothing to do with ActiveRecord classes. Yes, they may be similar. Maybe some names will be duplicated, but that's another layer. It should be framework-free, pure objects. PORO.&lt;br /&gt;
&lt;br /&gt;
The deployment way leads to the question - &lt;b&gt;What's the point of building an object model in memory, just to run one use-case and it all disappears?&lt;/b&gt; It's a waste. That's what happens when you build a domain layer based on database (ActiveRecord) data in a typical mongrel/passenger/heroku environment.&lt;br /&gt;
&lt;br /&gt;
I'm experimenting with running Rails in a threaded environment (Thin allows it). It means that Rails is run in a single process and all requests come as threads. It's promising and very liberating - you can have your own Ruby objects, without being restricted by the ActiveRecord problems. I will blog more about it, soon.&lt;br /&gt;
&lt;br /&gt;
There are problems, though. This approach requires a different scaling mechanism (but it also move the scaling need further to the future by speeding things up - your data is now in memory). Another problem is that you need to synchronize your domain layer with the ActiveRecord layer.&lt;br /&gt;
&lt;br /&gt;
Despite the problems, I think that this approach has some potential. Contact me, if you would like to help me with this research.&lt;br /&gt;
&lt;br /&gt;
Avdi also has some interesting ideas about the ActiveRecord separation in his book - &lt;a href="http://avdi.org/devblog/2011/11/15/early-access-beta-of-objects-on-rails-now-available-2/"&gt;"Objects on Rails"&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use cases&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The synchronization part can be done using the use-cases layer. Read about it here:&amp;nbsp;&lt;a href="http://blog.firsthand.ca/2011/12/your-rails-application-is-missing.html"&gt;http://blog.firsthand.ca/2011/12/your-rails-application-is-missing.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The use-case object can synchronize the two parts together, but you need to remember about keeping it consistent (either by transactioning it or by having a synchronizg thread).&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Use cases alone are an awesome idea&lt;/b&gt;. Imagine that all the changes to your system that are triggered by a user or another actor come through a use-case object. This way, you're nicely exposing all the actors playing together and you can expose your real architecture.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ActiveRecord is changing in Rails 4&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
Look at this commit:&amp;nbsp;&lt;a href="https://github.com/rails/rails/commit/00318e9bdfc346a57cab34b2ec3724f3e9605ac1"&gt;https://github.com/rails/rails/commit/00318e9bdfc346a57cab34b2ec3724f3e9605ac1&lt;/a&gt;&lt;br /&gt;
It seems to be a small change, but it will allow extending your objects with the persistence responsibility runtime with DCI. Wouldn't that be cool?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;DCI&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
You knew that I would mention DCI, didn't you? :) Yeah, I'm a big fan of DCI, just for the use-cases alone. They call it contexts, but it's the same meaning. The idea of DCI spreads nicely in the Rails world, but what worries me it's only the idea of extending objects runtime that is being spread. Runtime extending can easily bring you to a mess if you're not controlling who can extend any object. It's the context. If you're extending model objects inside other model objects, then you're doing it wrong, I'm sorry. Lessons learnt, trust me.&lt;br /&gt;
&lt;br /&gt;
Read more about DCI on my blog posts:&lt;br /&gt;
&lt;a href="http://andrzejonsoftware.blogspot.com/2011/12/dci-for-dummies.html"&gt;http://andrzejonsoftware.blogspot.com/2011/12/dci-for-dummies.html&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://andrzejonsoftware.blogspot.com/2011/02/dci-and-rails.html"&gt;http://andrzejonsoftware.blogspot.com/2011/02/dci-and-rails.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
You should also read "Lean architecture" book which is a deep introduction to the DCI way of thinking.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Rails is cool, if combined with classical OOP.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Remember about TDD and testing.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Separate backend from a frontend.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;ActiveRecord is not your domain layer.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Learn DCI.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Think in use cases.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Attend the &lt;a href="http://wrocloverb.com/"&gt;wroc_love.rb conference&lt;/a&gt;&amp;nbsp;in Wrocław, Poland.&amp;nbsp;There will be many Rails OOP related talks.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://c4p.wrocloverb.com/"&gt;Send us your ideas for talks&lt;/a&gt; (you have my vote if it's Rails OOP related :) ) - I'm one of the organizers.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;b&gt;Bonus&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;Uncle Bob talk from RubyMidwest&lt;/b&gt;&lt;br /&gt;
&lt;a href="http://confreaks.net/videos/759-rubymidwest2011-keynote-architecture-the-lost-years"&gt;http://confreaks.net/videos/759-rubymidwest2011-keynote-architecture-the-lost-years&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
It's one of the most important talks I have seen recently. You must watch it. It will change the way you think about Rails apps.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Thanks!&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5547140810240599830/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5547140810240599830" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5547140810240599830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5547140810240599830?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/rails-is-still-cool.html" title="Rails is still cool" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total></entry><entry gd:etag="W/&quot;DEIGQHszeCp7ImA9WhRWEk0.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-5348575405044230778</id><published>2011-12-30T00:55:00.000Z</published><updated>2011-12-30T00:55:21.580Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-30T00:55:21.580Z</app:edited><title>Small, deployable commits</title><content type="html">We've had an interesting discussion at our stand-up today. The discussion was triggered by Jan Filipowski post on "&lt;a href="http://agiler.net/2011/12/early-commiting-in-tdd-questions/"&gt;early commiting in TDD&lt;/a&gt;".&lt;br /&gt;
&lt;br /&gt;
The main questions are:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Should I refactor before every commit?&lt;/li&gt;
&lt;li&gt;Should a commit pass all tests?&lt;/li&gt;
&lt;li&gt;What units of code should be code-reviewed?&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
It got me thinking about my current approach and about my "ideal world" approach.&lt;/div&gt;
&lt;div&gt;
I'm a big fan of the idea of &lt;b&gt;continuous deployment&lt;/b&gt;. It means that every commit, after passing all tests, can be automatically deployed.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I'm not there yet. I try to work with very &lt;b&gt;short commits, often it's only 2-line changes&lt;/b&gt;. However, I still miss an infrastructure which could automatically push this commit, test it and deploy. It's not that it's difficult to prepare, it's just some kind of a psychological bareer. It's definitely something I want to improve as soon as possible.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Sometimes it's hard to have deployable commits. Recently we've been upgrading our app to Rails 3.1 and it's not something that can be done in one commit.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Going back to questions:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Should I refactor before every commit?&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Refactoring is part of a workflow, but I wouldn't say it should part of every commit. Sometimes a commit can be just the red-green part, and it's the next commit that does the "refactor" part.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Should a commit pass all tests?&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
This is a tricky one. In my ideal world - yes, because it should be deployable. Is it hard to achieve in practice? I'm wondering if there's a conflict between a deployable commit and one that fails on some tests. &amp;nbsp;Maybe it's fine to have some tests failing, if they are not part of the code that is being used in production?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&amp;nbsp;What units of code should be code-reviewed?&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
We tend to make code reviews using GitHub commit comments. They're fine, but sometimes I comment on something that was changed 3 commits later, which makes my comment irrelevant.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Obviously it all depends on a project. In most cases I think we shouldn't be too serious with the code reviews comments. In my opinion code reviews should help us triggering some coding/architecture discussions, they shouldn't be too formal. &lt;b&gt;I don't like proceses which require code reviews before the code goes into production&lt;/b&gt; - we should trust each other that nothing stupid gets deployed. If we treat a code review as a tool for better communication then it's not that important if a comment is about a code that changed later or not.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
How about you? How often do you commit?&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/5348575405044230778/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=5348575405044230778" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5348575405044230778?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/5348575405044230778?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/small-deployable-commits.html" title="Small, deployable commits" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>8</thr:total></entry><entry gd:etag="W/&quot;DU8NQ3s6cCp7ImA9WhRXEkk.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-8566622531662060269</id><published>2011-12-18T21:16:00.000Z</published><updated>2011-12-18T22:38:12.518Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-18T22:38:12.518Z</app:edited><title>args, opts, params</title><content type="html">It's quite popular, especially in Ruby code, to see methods like this (note the method arguments):&lt;br /&gt;
&lt;pre class="ruby" name="code"&gt;def show(args)
  some_other_object(args)
end
&lt;/pre&gt;
or

&lt;br /&gt;
&lt;pre class="ruby" name="code"&gt;def show(opts)
  .. lots of code
  bar = opts[:foo]
  opts[:bar]
end
&lt;/pre&gt;
and also:

&lt;br /&gt;
&lt;pre class="ruby" name="code"&gt;def show(name, params)
  some_other_object(name, params[:foo])
end
&lt;/pre&gt;
I see some problems with such code:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. It's hard to tell, when you call the method, what is really required/expected to pass in.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's less of a problem, when you can see in the method body what is used. But it's not always the case. Often the params are passed further, so you have to look around and think hard how the params are used.&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;2. (args, opts, params) as names sound very generic, they don't tell me too much.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I understand that hashes are quire useful sometimes. But it's a similar situation like the one where we would call a variable a var_1.&lt;br /&gt;
Why don't we, at least, give them good names, like address_hash or html_options or maybe game_configuration?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. It's a missing object smell.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Very often, to me, the examples above are code smells. There's a missing object somewhere. Especially when this data is passed further. Maybe it's Address object, maybe PopupContent, whatever sounds good in your domain.


&lt;br /&gt;
&lt;br /&gt;
What's your opinion?</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/8566622531662060269/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=8566622531662060269" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/8566622531662060269?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/8566622531662060269?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/args-opts-params.html" title="args, opts, params" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;Dk4ASHY_eip7ImA9WhRXEEs.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-6670279847354016948</id><published>2011-12-16T18:54:00.000Z</published><updated>2011-12-16T19:49:09.842Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-16T19:49:09.842Z</app:edited><title>DCI for dummies</title><content type="html">&lt;br /&gt;The metaphor of DCI is a &lt;b&gt;theatre&lt;/b&gt;. The context is the director. Chooses who plays what, instruct them how to do it and then let them play.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Theory&lt;/b&gt;:&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;Expose use-cases (context) as first-class citizens of your code.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Each use-case selects which objects are needed for this use-case.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Extend the objects only with the roles that are needed in this use-case.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Start the interaction.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;
&lt;b&gt;Example&lt;/b&gt;:&lt;br /&gt;&lt;br /&gt;Buying a product.&lt;br /&gt;&lt;ol&gt;
&lt;li&gt;UserBuysAProduct object, that can be executed.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Objects/actors needed: user, shop&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Extend user with a Buyer role and shop with ProductCatalogue and OrderManager.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;call shop.buy_product(user, product)&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/6670279847354016948/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=6670279847354016948" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6670279847354016948?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6670279847354016948?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/dci-for-dummies.html" title="DCI for dummies" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;DkUHRX45fSp7ImA9WhRQEU4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-6159315321857793307</id><published>2011-12-06T00:48:00.001Z</published><updated>2011-12-06T01:17:14.025Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-06T01:17:14.025Z</app:edited><title>Continuous integration - some tips</title><content type="html">Continuous integration server is a must for every non-basic project.&lt;br /&gt;
&lt;br /&gt;
Here are some of my tips for working with CI servers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Notifications&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
IRC, email, campfire - use what fits best for you. Ideally, the notification should come with some info about the code changes that triggered the build. &lt;a href="http://rails.arkency.com/team"&gt;We&lt;/a&gt; use IRC - we've got an IRC channel for every project we work on, so the notifications go to the correct channel.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Build time&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's a huge topic. It's so difficult to keep the build time short for every project. I have to admit we've got projects where build time takes 20 minutes. My goal is to get down to below 10 minutes for existing projects and try to keep the new projects below 3 minutes. Slow builds have a very bad impact on so many things. The feedback is late. People tend not to run builds on local machines.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Local builds&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
It's great that you have a CI server, but the goal is also that all tests can be run on every developer machine in a decent time.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Architecture decisions&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
That's the most surprising effect of using tests and CI. Once we got to the point where many of our projects have the slow build problem we investigated our technology choices. In many cases the slowness came from using Selenium. Selenium is the only "right" tool when you have an app that is a mix of server-side logic and client-side code (JS). &lt;b&gt;It seems, surprisingly, that many of our projects could be turned into one-page CoffeeScript apps&lt;/b&gt;. Obviously it's not an easy goal (and not always possible). It's changing the way we architecture our apps. If the split is achieved you can test the CS code in isolation from the server-side and then test the server-side API, also in separation, but without Selenium.&lt;br /&gt;
Selenium is cool, but it has the drawbacks of being slow and unreliable.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Unreliable tests&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
If you're using Selenium, then you already know what I mean. I hate this fact but sometimes we've got build failures which shouldn't appear, they're most of the time timing issues. It's a hard situation to have. The important thing to remember is that we (the team) are all in it. Every team member should investigate the problem and try to fix them - sometimes adding a sleep (a hack, I know) solves the problem.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Who's responsible for failures?&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
I like the idea that the last person who triggered a failing build is responsible for fixing it. It's hard to get to this point, especially if your build is unreliable. This leads to:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Never leave a broken build&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
This is the biggest sin when working with CI servers. If I want to start coding and I see that a build is broken and no one seem to care then it's very depressing to me. In practice, it means that you should commit your changes some time before you finish your work, so that the CI can run it and get you the result back. If it's broken, try to fix that as much as you can. It's less of a sin when the failure comes from unreliability, but leaving a broken build caused by your changes is unforgettable :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Summary&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
A green, fast build run frequently on the CI server is a sign of a healthy project. If there's anything broken with the build process, look at it. It's often a smell showing you that something can be wrong in your process. Don't ignore that.&lt;br /&gt;
&lt;br /&gt;
Any tips from your experience?</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/6159315321857793307/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=6159315321857793307" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6159315321857793307?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/6159315321857793307?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/continuous-integration-some-tips.html" title="Continuous integration - some tips" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>10</thr:total></entry><entry gd:etag="W/&quot;C0EHSX85eCp7ImA9WhRQEE4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-3057388885454051596</id><published>2011-12-04T20:34:00.001Z</published><updated>2011-12-04T20:47:18.120Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-04T20:47:18.120Z</app:edited><title>CoffeeScript is the fresh air</title><content type="html">When I started using Ruby and Rails in 2004 I&amp;nbsp;immediately&amp;nbsp;knew that Rails is going to be huge. At that time I was working mostly with Java.&lt;br /&gt;
&lt;br /&gt;
Ruby and Rails brought so much joy to my programming world that it was kind of a revolution in my programming passion. This revolution is still going on, I'm still happy with Ruby and Rails even if I sometimes criticize some aspects of it.&lt;br /&gt;
&lt;br /&gt;
There is however a new thing that triggered a new (r)evolution in my programming world.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;This thing is called CoffeeScript.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I know that Coffee is only a "patch" to JavaScript, but for me this slight change is huge. The syntax is the prettiest combination of Ruby and Python that I have ever seen.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;The code written in Coffee is so pretty that it almost allows you to think at new levels of abstraction&lt;/b&gt;. Yes, it's that huge to me.&lt;br /&gt;
&lt;br /&gt;
I never especially liked working with JavaScript on the front-end. I preferred to focus on Ruby backends. Now it's harder to me to switch from frontend code to server Ruby code.&lt;br /&gt;
&lt;br /&gt;
I still love Ruby, but CoffeeScript is officially becoming my new passion, equal to Ruby. If you haven't given it a try, then you should. It's so worth it.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/3057388885454051596/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=3057388885454051596" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3057388885454051596?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3057388885454051596?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/12/coffeescript-is-fresh-air.html" title="CoffeeScript is the fresh air" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;C0MMQXc6eyp7ImA9WhJTFk4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-8053910267322029907</id><published>2011-09-25T10:36:00.000Z</published><updated>2012-06-25T13:38:00.913Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T13:38:00.913Z</app:edited><title>Rails is not MVC</title><content type="html">There is a terminology problem in the Rails community.&lt;br /&gt;
&lt;br /&gt;
Everyone promotes Rails as a MVC framework. I did that as well. However, the truth is that &lt;b&gt;Rails represents the &lt;a href="http://en.wikipedia.org/wiki/Model2"&gt;Model2&lt;/a&gt; architecture. It's not MVC.&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I know it's just a definition issue. Maybe we shouldn't care. It wasn't really a problem until recently. We see the rise of the &lt;a href="http://andrzejonsoftware.blogspot.com/2011/09/3-steps-to-mvc-in-javascript.html"&gt;JavaScript MVC&lt;/a&gt; topic, which is an awesome thing. The browser clients with its JS engines can have a real MVC, as opposed to Model2.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;OK, so what's the difference?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In short, we're talking about MVC when a model can notify (through the Observer pattern) the views about the changes. It's not possible in a classical Rails app (it's possible when you use WebSockets, Pusher or a similar technology, but it's not so popular yet.). MVC was popular in desktop apps.&lt;br /&gt;
&lt;br /&gt;
On the other hand, &lt;a href="http://en.wikipedia.org/wiki/Model2"&gt;Model2&lt;/a&gt; is exactly what we do with Rails. We don't notify the views from the model, the controller simply passes the model data to the views and handles the html generation which is then sent to the browser.&lt;br /&gt;
&lt;br /&gt;
There's an interesting pattern evolving recently that a Rails app simply serves as a backend for a mobile app and all it does is exposing a JSON/REST API. It's similar to Model2, but instead of generating HTML it generates JSON. Still, it's not MVC.&lt;br /&gt;
&lt;br /&gt;
You can read more about UI architectures in this &lt;a href="http://www.martinfowler.com/eaaDev/uiArchs.html"&gt;article&lt;/a&gt; by Martin Fowler&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Why is it important?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
It's becoming an issue now, because we start talking more about the JavaScript MVC. The JavaScript MVC is a real MVC. The models can easily notify the views. Often, when you talk to people being introduced to the JS MVC they seem to be confused and try to implement the Model2 pattern on the client side, which in my opinion is ridiculous.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;What shall we do about the Model2 and MVC confusion?&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I see three choices.&lt;br /&gt;
&lt;br /&gt;
The first one is to say that MVC changed its original meaning and Model2 can also be called MVC. In that case we can start using terms like "classic MVC" or "real MVC" for the old MVC. This is what is happening now, but I don't think that changing definitions is a good idea. It brings even more confusion.&lt;br /&gt;
&lt;br /&gt;
The second way is to &lt;b&gt;promote the fact that Rails represents a Model2 architecture and MVC is reserved to, well, MVC&lt;/b&gt;. It's going to be hard, but we will keep the definitions stable.&lt;br /&gt;
&lt;br /&gt;
The third way is to just ignore the confusion. Who cares?&lt;br /&gt;
&lt;br /&gt;
I decided to go with the second option. What's the best way in your opinion?
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/8053910267322029907/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=8053910267322029907" title="27 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/8053910267322029907?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/8053910267322029907?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/09/rails-is-not-mvc.html" title="Rails is not MVC" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>27</thr:total></entry><entry gd:etag="W/&quot;CEcERH0-cCp7ImA9WhJTFk4.&quot;"><id>tag:blogger.com,1999:blog-7821856652257554779.post-3790319761649671620</id><published>2011-09-24T19:12:00.000Z</published><updated>2012-06-25T13:46:45.358Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-25T13:46:45.358Z</app:edited><title>3 steps to MVC in JavaScript</title><content type="html">&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Read this article&amp;nbsp;&lt;a href="http://michaux.ca/articles/mvc-architecture-for-javascript-applications"&gt;MVC Architecture for JavaScript Applications&lt;/a&gt; by Peter Michaux. It's a must-read and it nicely explains how the observer pattern works in the classic MVC. (Keep in mind that the MVC that you know from Rails/Django is a limited MVC, that's a topic for another post).&lt;/li&gt;
&lt;li&gt;Use &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone&lt;/a&gt; and &lt;a href="http://documentcloud.github.com/underscore/"&gt;Underscore&lt;/a&gt; to handle events or roll your own observer mechanism (as described in Peter's article).&lt;/li&gt;
&lt;li&gt;(optional) Use &lt;a href="http://jashkenas.github.com/coffee-script/"&gt;CoffeeScript&lt;/a&gt; to make your code prettier.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
Let me quote Peter Michaux:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;
In a nutshell the classic MVC architecture work like this. There is a model that is at the heart of the whole thing. If the model changes, it notifies its observers that a change occurred. The view is the stuff you can see and the view observes the model. When the view is notified that the model has changed, the view changes its appearance. The user can interact with the view (e.g. clicking stuff) but the view doesn’t know what to do. So the view tells the controller what the user did and assumes the controller knows what to do. The controller appropriately changes the model. And around and around it goes.&lt;/blockquote&gt;
&lt;br /&gt;
In the&amp;nbsp;&lt;a href="http://gameboxed.com/"&gt;GameBoxed&lt;/a&gt;&amp;nbsp;platform, we have a Monopoly-like Facebook game. There's a concept of a player (this is the model). A player, after rolling a dice, can receive points and when he does we need to update the player-details box.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;script src="https://gist.github.com/1239676.js?file=MVC_with_CoffeeScript.coffee"&gt;
&lt;/script&gt;
&lt;br /&gt;
&lt;br /&gt;
When the page is loaded (our games are one-page apps, no full reloads), the Monopoly object is initialized. It's a facade object responsible for initializing models, views and controllers and wiring them together.&lt;br /&gt;
&lt;br /&gt;
At some point thanks to some users actions the player.addPoints method is called which triggers the "player:updated" event with some arguments. Thanks to the controller (the bind method), the PlayerView object is notified that something interesting happened and the view updates the html (with some jquery helpers).&lt;br /&gt;
&lt;br /&gt;
This pattern is very useful and can be used in most of the typical UI scenarios. Let me know what you think about it.

&lt;br /&gt;
&amp;nbsp;If you read this far you should &lt;a href="http://www.twitter.com/andrzejkrzywda" rel="nofollow" target="_new"&gt;&lt;img alt="Follow andrzejkrzywda on Twitter" src="http://twitter-badges.s3.amazonaws.com/follow_me-a.png" /&gt;&lt;/a&gt; and &lt;a href="http://feeds.feedburner.com/andrzejkrzywda"&gt;subscribe to my RSS&lt;/a&gt;.</content><link rel="replies" type="application/atom+xml" href="http://andrzejonsoftware.blogspot.com/feeds/3790319761649671620/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=7821856652257554779&amp;postID=3790319761649671620" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3790319761649671620?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7821856652257554779/posts/default/3790319761649671620?v=2" /><link rel="alternate" type="text/html" href="http://andrzejonsoftware.blogspot.com/2011/09/3-steps-to-mvc-in-javascript.html" title="3 steps to MVC in JavaScript" /><author><name>Andrzej Krzywda</name><uri>http://www.blogger.com/profile/06399276063142826365</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry></feed>
