<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6178209</id><updated>2012-01-09T10:55:19.131-06:00</updated><category term='kanban'/><category term='mocks'/><category term='design'/><category term='lean'/><category term='testing'/><category term='agile'/><category term='DSL'/><category term='Redpoint'/><title type='text'>Igor's Blog</title><subtitle type='html'>&lt;b&gt;"... no matter what they tell you, it's always a people problem!"&lt;/b&gt;</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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>25</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6178209.post-651736699346485609</id><published>2009-07-16T13:08:00.010-05:00</published><updated>2009-07-16T22:45:30.942-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DSL'/><category scheme='http://www.blogger.com/atom/ns#' term='Redpoint'/><title type='text'>Modeling for Domain Evolution</title><content type='html'>A constant goal of mine is to express intent while developing software systems. In the begging, I spent a lot of time trying to create a better Object Oriented Design hoping that the abstraction level would be enough to clearly represent a business model. Of course, this wasn't enough and I continue looking for better abstraction levels.&lt;br /&gt;&lt;br /&gt;The next step was my obsession with Design Patterns and Frameworks. Common understanding of the problem, at least among developers helped a lot but business people still couldn't easily relate a system solution to the actual business model.&lt;br /&gt;&lt;br /&gt;Continuing in that direction led me to discover the incredibly valuable book - Domain Driven Design and just a little later the somehow related concepts behind an interesting but not very popular framework called "Naked Objects". Domain Driven Design was huge advanced towards expressing intent and introduced an invaluable concept about ubiquitous language.&lt;br /&gt;&lt;br /&gt;At that point, the level of abstraction was pretty good in relation to designing domain models, but specifying the behavior of a system was somehow problematic. Again, mostly a change in the perception and the way of thinking rather than technology advances led me to the concept of Behavior Driven Design. Specifying system behavior in an executable way was an impressive step but a little hard to achieve with the current static programming languages that most of the systems were build at that time.&lt;br /&gt;&lt;br /&gt;Didn't take me long to discover the disruptive power of dynamic languages like Ruby and all meta programming concepts that came with them. Additionally, I discovered a much different way of designing APIs in the form of Fluent Interfaces. That allowed me to express business intent through a software solution in an almost natural english language form that business people could start understanding.&lt;br /&gt;&lt;br /&gt;Interestingly enough, it turned out that even this is not enough because of a simple fact - business people use a natural language only to define different specific languages that better describe their business domains. Well, not surprisingly this realization led me to the concept of Domain Specific Languages (DSL).&lt;br /&gt;&lt;br /&gt;After the initial euphoria of designing and implementing Domain Specific Languages, I start looking for the same impressive tool support that I was used to while working with other well established general purpose programming languages. It turned out that there is not a better time for that with current release of most of the main players in this area (Intentional Software, JetBrains, MS Oslo, Eclipse xText,...)  delivering solutions for a really disruptive concept summarized as Language Workbenches.&lt;br /&gt;&lt;br /&gt;In order to visually represent this path towards delivering better software solutions, I created "My Curve of Abstraction Towards - Expressing Intent &amp;amp; Ubiquitous Language"&lt;br /&gt;&lt;br /&gt;&lt;img style="width: 400px; height: 307px;" src="http://1.bp.blogspot.com/_7aYqj-OFwPA/Sl9t4TByriI/AAAAAAAAAWU/NEaNPyVYFx0/s400/curve.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5359122895542070818" /&gt;&lt;br /&gt;&lt;br /&gt;I don't know if DSLs and Language Workbenches would be successful in practice, but those concepts would definitely change the way in which I approach and design software solutions. In most of the system that I have built until now I used programming languages to specify a domain model and the behavior of a system. Recently, however, I worked on software solutions that had to be model for domain evaluation. Basically, I used programming languages to define a business model definition and structure via other languages and notations, or so called Language Oriented Programing.&lt;br /&gt;&lt;br /&gt;&lt;img style="cursor:pointer; width: 400px; height: 303px;" src="http://3.bp.blogspot.com/_7aYqj-OFwPA/Sl9uDtdjCoI/AAAAAAAAAWc/V1IPu8UzJv8/s400/structure.png" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;This is actually the topic in my presentation that I gave recently called - &lt;a href="http://docs.google.com/present/view?id=ajjbqnfjz9gv_248594ws53m"&gt;"Domain Specific Languages- ... a forgotten interface metaphor with renewed tooling support"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/present/embed?id=ajjbqnfjz9gv_248594ws53m&amp;amp;size=m" frameborder="0" width="555" height="451"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-651736699346485609?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.igorstoyanov.com/2009/07/modeling-for-domain-evolution.html' title='Modeling for Domain Evolution'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/651736699346485609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=651736699346485609&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/651736699346485609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/651736699346485609'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/07/modeling-for-domain-evolution.html' title='Modeling for Domain Evolution'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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://1.bp.blogspot.com/_7aYqj-OFwPA/Sl9t4TByriI/AAAAAAAAAWU/NEaNPyVYFx0/s72-c/curve.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6178209.post-3557994876125577488</id><published>2009-07-15T19:15:00.011-05:00</published><updated>2009-07-15T19:39:47.119-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='kanban'/><category scheme='http://www.blogger.com/atom/ns#' term='lean'/><category scheme='http://www.blogger.com/atom/ns#' term='Redpoint'/><title type='text'>Agile within Constraints: Embrace Kanban Limits</title><content type='html'>Every time when I try to introduce Kanban ("visual card/board") Lean system in an Agile team I got the same question - Kanban looks exactly the same as the current index card board, so what is the difference? As I mentioned in my &lt;a href="http://blog.igorstoyanov.com/2009/07/agile-within-constraints-identify.html"&gt;previous post&lt;/a&gt;, the main difference that really defines a Kanban system are limits. Logically, the next question to follow is why we need limits.&lt;br /&gt;&lt;br /&gt;Well, there is a problem that I see occurring often with the basic index-card task board. There is nothing to prevent accumulating a big pile of story cards that are work in progress. Usually, the bottleneck could happen in multiple places. Sometimes, it is  the huge backlog that is constantly and prematurely prioritized, other times it is the familiar pattern of busy developers in the beginning of an iteration and busy BAs and QAs at the end of the iteration. More often than not a big  story card queue for testing is left beyond a current iteration without any timely feedback.&lt;br /&gt;&lt;br /&gt;Actually, an iteration, which is central part of an Agile practices is a natural time-boxing constraint to how much Work in Progress can be accumulated. However, the time-boxing limit doesn't help in optimizing the overall team workflow and throughput, doesn't avoid premature work.&lt;br /&gt;&lt;br /&gt;Let's take a common example of an agile story board:&lt;img style="margin: 5px 15px 0px 0;width:600px;height:260px;" src="http://3.bp.blogspot.com/_7aYqj-OFwPA/Sl5ycw1HzoI/AAAAAAAAAWE/OTy9nCRXhcw/s400/agile-story-board.jpg" border="0" alt="" /&gt;&lt;br /&gt;&lt;br /&gt;I see some bottleneck from the pile of story cards in the testing backlog on the picture above but I can't tell for sure if this is a problem. I don't know what the team testing capacity is because looking at the story board I don't see visual indication of the current limit - the time left to the end of an iteration.&lt;br /&gt;&lt;br /&gt;So, I have to wait to the end of the iteration to know for sure if there is a problem and I would still not find out where the bottleneck is. Even if all the story cards are completed on time, the basic index-card task board with time-boxing limit show team progress during an iteration but doesn't indicate whether the team has optimal throughput. Also, accumulating a big backlog at some stage of the work in progress (as the big pile of cards in the testing backlog on the picture above)  could delay feedbacks (development going in wrong direction until BAs/QAs complete review/testing) and consequently allow for premature work to be done.&lt;br /&gt;&lt;br /&gt;At the end, one of the goals of a development team should be to maximize overall team throughput and reduce waste through constantly optimizing team workflow and enhancing teamwork. A Kanban Lean system is one mechanism that can be used to control a workflow and indicate waste in form of bottlenecks.&lt;br /&gt;&lt;br /&gt;Kanban is what enables a pull system for just-in-time work. Very simply, there is a queue of work, which goes through a number of stages of development until its done. When someone needs new work to do, they pull it from their upstream queue. Not much different from an Agile story board until here. However, the important element, as I mentioned above, is different type of limits.  There are two basic limits – Queue limits and Work in Progress limits.&lt;br /&gt;&lt;br /&gt;Queue limits try to achieve just-in-time work and are designed to avoid premature work. The limit should be large enough to keep the team busy (i.e. there is always something in it for the team to start work on), but small enough to avoid premature prioritization (i.e. having things sitting in the queue for too long before they are begun). The later is what  pressingly is missing in a typical Agile team story board.&lt;br /&gt;&lt;br /&gt;Work In Progress limits are designed to reduce multi-tasking and maximize throughput. The former concept of reducing context switching and performing task sequentially to yield results sooner is very familiar to Agile teams. The later, however, is usually overlooked in typical Agile settings. Maximizing overall throughput by decreasing Work in Progress is often seen in various areas. Simple examples of this effect are traffic jams, where traffic speed reduces as more traffic builds up.&lt;br /&gt;&lt;img style="float:left; margin:0;cursor:pointer;width: 400px; height: 300px;" src="http://1.bp.blogspot.com/_7aYqj-OFwPA/Sl50v7ONWlI/AAAAAAAAAWM/1PkLV7D-urw/s400/table.png" border="0" alt="" /&gt;Limiting Queue size and Work In Progress like this can seem unusual for teams, and there is often a worry that team members will be idle because they are having no work to do, but are unable to pull any new work. However, the Queue and WIP limit sizes can depend on type of work and size of a team and should be adjusted to achieve maximum flow and reduce bottleneck. One easy approach is to adjust the WIP limits to the number of available people/pairs in a team. For example, if there are 6 developers in a team and they work in pairs, the size of development Work in Progress limit should be 3. The development Queue size limit should be large enough to keep continues development Work in Progress (so at least 3 story cards) but not big enough to allow premature prioritization on every developer pull (so this would require some adjustment and depends on the Average Developers and BAs Completion Rates as well as the number of BAs. I think that twice the size of WIP could be a good start as a queue limit).&lt;br /&gt;&lt;br /&gt;Finally, the consequences of using a Kanban system could be a little surprising or even controversial and could include eliminating the Story Card Backlog (because the immediate queue is the only work of interest), time-boxed iterations (i.e. Sprints) can be eliminated as well because work is pulled as necessary, and consequently estimations can be eliminated because work is not planned into iterations.&lt;br /&gt;&lt;br /&gt;Now, most of the questions at this point would be along the lines that if an Agile team isn't estimating or planning within iterations(Sprints), how it can make reliable commitments in front of business product owners.&lt;br /&gt;&lt;br /&gt;As a start, Kanban could help you eliminated iterations, estimations and backlogs but can work equally well within a time-boxed limit and with a reasonable backlog size. However, the real answer to that questions is Cadence Lean system, which is an approach to achieve commitment and reliability with a Kanban system and for which I will continue in further post on this topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-3557994876125577488?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.igorstoyanov.com/2009/07/agile-within-constraints-embrace-kanban.html' title='Agile within Constraints: Embrace Kanban Limits'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/3557994876125577488/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=3557994876125577488&amp;isPopup=true' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/3557994876125577488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/3557994876125577488'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/07/agile-within-constraints-embrace-kanban.html' title='Agile within Constraints: Embrace Kanban Limits'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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://3.bp.blogspot.com/_7aYqj-OFwPA/Sl5ycw1HzoI/AAAAAAAAAWE/OTy9nCRXhcw/s72-c/agile-story-board.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6178209.post-705070515504221949</id><published>2009-07-09T23:55:00.005-05:00</published><updated>2009-07-15T19:41:14.865-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='lean'/><category scheme='http://www.blogger.com/atom/ns#' term='Redpoint'/><title type='text'>Agile within Constraints: Identify</title><content type='html'>All parents know what is going to happen when a kid walks in a toy store. That is why, every parent knows to better set some kind of expectations and constraints (like "…you can choose a toy but only one ..., one toy or nothing.") before entering a toy store (actually any store).&lt;br /&gt;&lt;br /&gt;Setting the right expectations and identifying all constraints can help achieve a given goal. Working within clearly identified constraints could make our solution leaner and more efficient. &lt;br /&gt;&lt;br /&gt;Interesting example of that idea is the classical children book "The Cat in the Hat". The author of the book, Dr. Seuss, had very clearly defined constraint - the book could only use a vocabulary of 225 words, so that beginning readers could read it. Dr. Seuss used clever combinations of the 225 words and a lot of illustrations to create a very interesting long lived story. &lt;br /&gt;&lt;br /&gt;Of course, a lot of similar examples could be found everywhere, especially in technology field. The HTTP protocol over TCP has been commonly criticized to be very constrained one and yet, exactly that constrained nature of this protocol is considered to be the main reason behind the wildly scalable and successful word wide web. &lt;br /&gt;&lt;br /&gt;Interestingly enough, most of the advices that one could get about web application scalability would come down to embracing system constraints and rely on them rather than try to overcome them. &lt;br /&gt;&lt;br /&gt;In fact, a constraint is a restriction on the degree of freedom you have in providing a solution. However, such a restriction on the degree of freedom could be utilized to convert complexity into simplicity. To illustrate that ask yourself how your perfect house would look like, or where you would like to be professionally in 5 years, or .... Easy questions but hard answers. The reason - prefect implies no constraints but perfect is hard if not possible to achieve. Now, if you include some constraints like the "perfect" house should not be more than 3 times your yearly salary, you would probably compromise somewhere but you would get to a solution much more easily. &lt;br /&gt;&lt;br /&gt;Embracing constraints to help provide leaner solutions is something that I am currently excited in retrospect to Agile. In fact, this was the main difference that I discovered while exploring Lean software development in recent years. The first time when I realized that was while working with Kanban ("visual card/board"), which is an essential part of Lean Software Development and for which I would write more in my &lt;a href="http://blog.igorstoyanov.com/2009/07/agile-within-constraints-embrace-kanban.html"&gt;next post&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-705070515504221949?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://blog.igorstoyanov.com/2009/07/agile-within-constraints-identify.html' title='Agile within Constraints: Identify'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/705070515504221949/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=705070515504221949&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/705070515504221949'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/705070515504221949'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/07/agile-within-constraints-identify.html' title='Agile within Constraints: Identify'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-7702619163696505253</id><published>2009-03-17T11:40:00.008-05:00</published><updated>2009-03-17T14:15:25.392-05:00</updated><title type='text'>URL Crawlability as Architectural Design Goal</title><content type='html'>&lt;p&gt;A lot of times during a system design a lot of architectural design decisions are based on architectural goals like performance, security, scalability, usability and so on.  I believe that url crawlability (or with other words - RESTful urls) is often neglected (especially in Java, PHP, ASP.Net….) but should be considered as one of the top priorities among all other architectural design goals for every web enabled system.&lt;/p&gt;&lt;p&gt;As usual, Ruby on Rails excels in this area too and I could only learn from it but in the realm of Java, even if you want to do it you would have incredibly hard time.  Almost all of the java web frameworks fail to provide a way to work with RESTful urls. A big exception to that is Stripes framework. The REST support is still missing, although it would be trivial to be implemented but RESTful urls are definitely there. &lt;/p&gt;&lt;p&gt;A lot of nice thing could be said about Stripes but better read it from their web site.&lt;br /&gt;The only thing that I would like to add about this framework is that I had the chance to work with it for the last 9 months extensively (after working more than a year with Rails) and I can say that, &lt;i&gt;in my opinion&lt;/i&gt;, this is not the best Java framework right now, but probably this is the ONLY Java &lt;b&gt;WEB&lt;/b&gt; framework right now (at least from the ones that I have evaluated – and this list is very long!). &lt;/p&gt;&lt;p&gt;I went a little off point but I just wanted to say that currently I consider url crawlability/RESTful urls as one very important architectural design goal with a lot of benefits coming out of it and my first criteria evaluating any web framework is whether it could support RESTful urls or not. &lt;/p&gt;&lt;p&gt;Is this an important consideration in your design?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-7702619163696505253?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2009/03/url-crawlability-as-architectural.html' title='URL Crawlability as Architectural Design Goal'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/7702619163696505253/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=7702619163696505253&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/7702619163696505253'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/7702619163696505253'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/03/url-crawlability-as-architectural.html' title='URL Crawlability as Architectural Design Goal'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-4149501103006698204</id><published>2009-02-23T21:07:00.003-06:00</published><updated>2009-02-23T21:26:05.967-06:00</updated><title type='text'>What I am excited about applying in the realm of software development lately</title><content type='html'>&lt;!--StartFragment--&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;color:#470D4F;"&gt;Recently, I had to answer to the questions:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;color:#470D4F;"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;What insight have you had lately in the realm of software development that you are excited about applying?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;color:#470D4F;"&gt;The answer turned out to be a little longer which made it a good candidate to post on my blog. So, there it is:&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;Well, there are a lot of interesting ideas that I am passionate to apply or improve in the technology area. Most of them are a few years old and there are successful examples of applying them, but still the majority of IT industry doesn't embrace them either because these ideas require a lot of effort and discipline or because it is mostly different mindset and vision.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;If I can summarize most of the ideas in one sentence, it would be – using the web as a platform coupled with lean and lightweight business model to give the ability to strategically position a company as an middleman or automated intermediary between the user and his or her online experience, between customers and producers, between data providers and data consumers.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;That includes a high accent on remixable data sources and data transformation, allowing users to control their own data and at the same time use their collective intelligence to generate new content or improve on the quality of existing data. (representing data in different formats –html, xml, json .. and on different platforms – mobile, browsers, desktop, real time positioning…., gather comments, ratings, reviews, adding own content, products…)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;Support lightweight programming models that allow for loosely coupled systems and enabling constant changes and enhancements. I believe that by using lightweight frameworks, simple architectural design and more dynamic type programming a technology team could enable a business model to be more flexible and efficient. (conventions over configurations, simple web services –REST, syndication of data, autonomous distributed systems with smart ends  )&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;For this to happen, I would think that the technology part of a company should concentrate on the core competency and re-use data or infrastructure services of others for everything else (storage services, virtual serves, emails, cloud computing and so on.)&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;Further, I think that businesses would have hard time in today's very competitive global economy if they don't go far and beyond for their users. From a technology point a view, I am very fascinated to implement features like real time monitoring of user behavior to find out what is valuable for them and what could be improve. Implementing features that would allow to enable and cooperate with users and not to direct or control them – simple user interface, intuitive searches, intelligently customizing application based on users behavior and data consolidation, different data formats, widgets, web service interfaces, content syndication and so on.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal" style="mso-pagination:none;mso-layout-grid-align:none; text-autospace:none"&gt;&lt;span style="font-family:Arial; mso-bidi-font-family:Arial;font-size:13.0pt;"&gt;Last but definitely not least, I am very passionate about software development practices and methodologies. Exciting ideas that I would like to try or improve on are – extremely frequent releases, different types of collaboration and intelligent gathering of various project information including natural processing language algorithms to improve communications and common understanding.&lt;/span&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Well, what are you excited about in the realm of software development recently?&lt;/p&gt;  &lt;!--EndFragment--&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-4149501103006698204?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2009/02/what-i-am-excited-about-applying-in.html' title='What I am excited about applying in the realm of software development lately'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/4149501103006698204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=4149501103006698204&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/4149501103006698204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/4149501103006698204'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/02/what-i-am-excited-about-applying-in.html' title='What I am excited about applying in the realm of software development lately'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-7919734622949109786</id><published>2009-02-22T23:13:00.005-06:00</published><updated>2009-02-22T23:30:29.189-06:00</updated><title type='text'>The Curve of Development Experience</title><content type='html'>&lt;div&gt;I start realizing recently that there are lots of debates about software best practice, design patterns, different frameworks or libraries.  What happens usually is that inexperienced software developers are usually obsessed (I was) with learning design patterns and the best frameworks out there.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;After a few years constantly trying to apply every possible design pattern or framework to any problem, I start realizing that I spent more time fighting with those frameworks than I benefited from them. Not to mention that using design patterns and so-called best practices could severely increase the complexity of a given code base if not used in the right context.&lt;br /&gt;&lt;br /&gt;At some point, you start asking yourself not only about the benefits but also about the negatives that a given framework, a design pattern or a best practice solution could bring. At this point, you are more inclined to go with the simplest possible solution – build whatever you need by yourself.&lt;br /&gt;&lt;br /&gt;Of course, sometimes you see more values in some frameworks or using design patterns and you start playing very balancing game.  So this is what I call "the curve of development experience".&lt;br /&gt;&lt;br /&gt;&lt;img src="http://lh4.ggpht.com/_7aYqj-OFwPA/SaIyB99q5SI/AAAAAAAAARI/SSjceophTIo/s800/curve_of_development_experience.jpg" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-7919734622949109786?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2009/02/curve-of-development-experience.html' title='The Curve of Development Experience'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/7919734622949109786/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=7919734622949109786&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/7919734622949109786'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/7919734622949109786'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2009/02/curve-of-development-experience.html' title='The Curve of Development Experience'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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://lh4.ggpht.com/_7aYqj-OFwPA/SaIyB99q5SI/AAAAAAAAARI/SSjceophTIo/s72-c/curve_of_development_experience.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6178209.post-8366200766515463654</id><published>2008-01-28T21:24:00.000-06:00</published><updated>2008-01-31T20:01:50.224-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mocks'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Observing Behavior</title><content type='html'>I had to write very simple counting method today. I started with a unit test that pretty much executes a method (which increment a count) and asserted that the count was incremented. This is the test that I wrote:&lt;br /&gt;&lt;pre&gt;public void testShouldRecordSystemException(){&lt;br /&gt;&lt;span&gt;     &lt;/span&gt;exceptionMonitor.recordSystemException();&lt;br /&gt;&lt;span&gt;     &lt;/span&gt;assertTrue(exceptionMonitor.getCurrentCount());&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;and this is the code that I was intending to write:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;public void recordSystemException() {&lt;br /&gt;storeNewTotal(++currentCount);&lt;br /&gt;}&lt;/pre&gt;       &lt;p&gt;The problems with this test are:&lt;br /&gt;&lt;span&gt;-&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-size:7;" &gt;         &lt;/span&gt;&lt;/span&gt;exposing internal state and breaking encapsulation with getCurrentCount() without anybody using it. (Yes, I know that I can make it protected instead of private, but this is not good enough for me. Changing private methods to protected in order to be tested is a topic, hugely discussed already in the blogsphere and I don’t have too much to add. I share the opinion that exposing private methods to protected just for testing looks like design smell and I try to avoid it. However, from time to time, I could make a method protected just for testing if this is the most pragmatic thing to do).&lt;br /&gt;&lt;span&gt;-&lt;span style="font-style: normal; font-variant: normal; font-weight: normal; line-height: normal; font-size-adjust: none; font-stretch: normal;font-size:7;" &gt;         &lt;/span&gt;&lt;/span&gt;This is pure state based testing. Although, sometimes state based testing is the better solution in many other cases verifying behavior is leading to much better design. &lt;/p&gt;    &lt;p&gt;As a result, this small test reminded me about one presentation that I gave in our office about a year ago. The presentation is about “&lt;b&gt;Mocking Abuse&lt;/b&gt;” but the final point of that presentation is that there is a middle ground between state base testing and interaction base testing (using mocks) that I call “&lt;b&gt;verifying observable behavior&lt;/b&gt;”. &lt;/p&gt;    &lt;p&gt;What that means is that this test should be changed to observe the behavior instead of verifying the object state:&lt;/p&gt;      &lt;pre&gt;public void testShouldRecordSystemException(){&lt;br /&gt;&lt;span&gt;         &lt;/span&gt;assertEqual(1, exceptionMonitor.recordSystemException());&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;What happened here is that the method recordSystemException() changed its return type from void to int:&lt;br /&gt;&lt;/p&gt;    &lt;pre&gt;public int recordSystemException() {&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;storeNewTotal(++currentCount);&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;return currentCount;&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;The first question that comes to mind is how to verify that the method executes correctly because you can pass the test above with implementation like:&lt;br /&gt;&lt;/p&gt;      &lt;pre&gt;public int recordSystemException() {&lt;br /&gt;&lt;span&gt;    &lt;/span&gt;return 1;&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;This is where the thinking about testing state vs verifying behavior should change. In practice, in order to verify behavior, we perform series of steps. Similarly, in mathematics we have so called “&lt;span&gt;Mathematical induction&lt;/span&gt;”. Very simplistically put,&lt;span&gt; a given statement is true for all natural numbers if &lt;/span&gt;the statement is true for 1, 2 …. n, and n + 1. Similarly, just one verification for verifying observable behavior is not enough:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;public void testShouldRecordSystemException(){&lt;br /&gt;&lt;span&gt;   &lt;/span&gt;&lt;span&gt;  &lt;/span&gt;for(int n = 1; n&lt; 5; n++){&lt;br /&gt;&lt;br /&gt;&lt;span&gt;&lt;/span&gt;       assertEquals(n, exceptionMonitor.recordSystemException());&lt;br /&gt;&lt;br /&gt;&lt;span&gt;     &lt;/span&gt;}&lt;br /&gt;}&lt;/pre&gt;  &lt;p&gt;Now, this test should make me implement the right behavior. &lt;/p&gt;    &lt;p&gt;That is not a ground braking technique or something not widely known. This is just a change in the way of thinking about design and testing. What is more, in functional languages like Ruby and Python this kind of thinking is encouraged from the fact that every method (function) has always a return value, which allows for observing the behavior of every method. &lt;/p&gt;    &lt;p&gt;So, back to the presentation that I mention earlier, it is about something similar. Generally, in our desire to avoid state based testing (which sometimes leads to poorer design, braking encapsulation and so on) we go to the other extreme with interactive testing using mocks (exposing implementation being one of the negative consequences). I already wrote way back about this development behavior in &lt;a href="http://igorstoyanov.blogspot.com/2005/10/stubs-or-mocks-state-or-behavior.html"&gt;Stubs or Mocks&lt;/a&gt; and &lt;a href="http://igorstoyanov.blogspot.com/2005/10/stubs-or-mocks-state-or-behavior_30.html"&gt;State or Behavior&lt;/a&gt;. &lt;/p&gt;    &lt;p&gt;This presentation is building the case on top of those two blog posts that mocks are not the new silver bullet and there is a middle ground between state based testing and interactive based testing that I call &lt;b&gt;verifying observable behavior. &lt;/b&gt;&lt;/p&gt;&lt;br /&gt;&lt;a href="http://docs.google.com/Presentation?id=ajjbqnfjz9gv_29cn5pb5vs"&gt;Mock Abuse!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://docs.google.com/EmbedSlideshow?docid=ajjbqnfjz9gv_29cn5pb5vs" frameborder="0" height="342" width="410"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;As usual, any feedbacks are welcome!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-8366200766515463654?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2008/01/observing-behavior.html' title='Observing Behavior'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/8366200766515463654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=8366200766515463654&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/8366200766515463654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/8366200766515463654'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2008/01/observing-behavior.html' title='Observing Behavior'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-2943186186851732483</id><published>2008-01-28T21:17:00.000-06:00</published><updated>2008-01-28T21:24:08.835-06:00</updated><title type='text'>Job Title</title><content type='html'>&lt;p&gt;For a long time, I am struggling to find my job title (yes, we put whatever titles we want in our company). Coming from a highly business (financial) background, I had hard time defining the title of my position in the IT world. &lt;/p&gt;    &lt;p&gt;I can’t call my self true “Software Engineer” because this title applies working in very technically oriented domains. “Software Developer” sounds good but since it is widely accepted term, it means different things to different people. Finally, I picked up “Business Developer”. This title was supposed to mean that I am very interested in solving business problems with any means possible (including prioritization, optimization of business workflows and processes and so on). Most importantly, however, it is about abstracting business models and managing the complexity of a business through a sophisticated use of software as a tool. &lt;/p&gt;    &lt;p&gt;Yes, you can imagine that this didn’t work out the way I intended to. Almost of all of the people thought about “Business Developer” to mean a person who develops the business of a company in a way of increasing the market share, market awareness and finding new clients (or something like that) . &lt;/p&gt;    &lt;p&gt;Later on, I realized that although sometimes I do provide small business optimizations and improvements most of the time I just solve pure software problems. Very often, I am solving those types of problem through heavy use of Google search. I search for similar problems and how other people solved them or didn’t solve them and then try to modify and apply the solution for my problem at hand. That’s why I decided that my title should be not something like “Java Developer” or “Ruby Developer” but rather “Google Developer”, meaning I can solve the problem in any language and tool with some extensive research on the web. &lt;/p&gt;    &lt;p&gt;Well, “Google Developer” probably means that I am a developer working for Google, so logically the next one coming to mine is “Search Developer” or “Research Developer”. As you can see, both titles have different meaning than what I want to imply. &lt;span&gt; &lt;/span&gt;For a while, I just give up and I came back to “Software Developer”. &lt;/p&gt;    &lt;p&gt;Not far ago, I was involved with a huge enterprise project. What I reconfirmed there was that usually the business people give requirements according to which a new software system should be built. However, based on many miscommunications, misunderstandings, different context, simple mistakes, a lot of compromises and the amount of time that takes to build an application the abstract business model together with the business workflows and processes built by the (gigantic) software team are not exactly as the business envisioned them (and sometimes even dramatically different). &lt;/p&gt;    &lt;p&gt;Very often the business (since it spent so much money for this) is forced to use and adjust to this new (different) business model. After a while, the whole business behavior of a department or an organization is determined by this new business model. &lt;/p&gt;    &lt;p&gt;So, there you go! It came out to me that no matter whether the business likes it or not, I am building and redesigning the business model, workflows and processes while building new software business systems. Based on this reasoning, I am now considering the titles “Business Modeling” or “Business Transformer”. &lt;/p&gt;    &lt;p&gt;And yes, they are still not on the target. “Business Modeling” is very good but it should be “Business Modeler”, which doesn’t sound good. “Business Transformer” sounds more like Robocop or something like that. &lt;/p&gt;    &lt;p&gt;Finally, I am back to just “Software Developer” whatever this means. It is difficult to escape the common understanding (misunderstanding) for what you do or want to do.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Any other suggestions or similar thoughts?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-2943186186851732483?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2008/01/job-title.html' title='Job Title'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/2943186186851732483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=2943186186851732483&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/2943186186851732483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/2943186186851732483'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2008/01/job-title.html' title='Job Title'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-117220775202705954</id><published>2007-02-22T23:11:00.000-06:00</published><updated>2007-02-22T23:23:55.656-06:00</updated><title type='text'>Filtering has_many Associations in Rails</title><content type='html'>&lt;style&gt;&lt;br /&gt;pre{&lt;br /&gt; background-color: #FFFFCC;&lt;br /&gt; border-style: solid;&lt;br /&gt; border-width: thin;&lt;br /&gt; border-color: Gray;&lt;br /&gt; padding: 4px 4px 4px 8px;&lt;br /&gt; margin-left: 2em;&lt;br /&gt; margin-right: 2em;&lt;br /&gt;}&lt;br /&gt;&lt;/style&gt;&lt;br /&gt;&lt;b&gt;... intro &lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;A few months ago, I read &lt;a href="http://weblog.jamisbuck.org/"&gt;Jamis Buck's&lt;/a&gt; blog entry &lt;a href="http://weblog.jamisbuck.org/2007/1/9/extending-activerecord-associations"&gt;Extending ActiveRecord associations&lt;/a&gt;. It's about filtering and memorizing the results for &lt;i&gt;has_many&lt;/i&gt; association based on some conditions. I found this to be useful and I bookmark it. Sure enough, it happens that I just needed similar functionality. However, it didn’t work exactly as I thought. I decided to post it here, so if I am doing something wrong, hopefully, somebody can correct me or in case somebody else has similar issues. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;So, this is an exact copy form Jamis’s blog entry of :&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Project &lt; ActiveRecord::Base&lt;br /&gt;  has_many :tasks, :dependent =&gt; :delete_all do&lt;br /&gt;    memoized_finder :active, "status = 'active'"&lt;br /&gt;    memoized_finder :inactive, "status = 'inactive'"&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Module&lt;br /&gt;  def memoized_finder(name, conditions=nil)&lt;br /&gt;    class_eval &lt;&lt;-STR&lt;br /&gt;      def #{name}(reload=false)&lt;br /&gt;        @#{name} = nil if reload&lt;br /&gt;        @#{name} ||= find(:all, :conditions =&gt; #{conditions.inspect})&lt;br /&gt;      end&lt;br /&gt;    STR&lt;br /&gt;  end&lt;br /&gt;end &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;... evaluation&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I created a file “/lib/ memoized_finder.rb” and included it in “/config/environment.rb”:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# Bootstrap the Rails environment, frameworks, and default configuration&lt;br /&gt;require File.join(File.dirname(__FILE__), 'boot')&lt;br /&gt;require File.join(File.dirname(__FILE__), '/../lib/memorize_finder')&lt;br /&gt;&lt;br /&gt;Rails::Initializer.run do |config|&lt;br /&gt;... ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;as it was mentioned in the comments for this post.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Then, I specified the expected behavior using rspec:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;context "Project has many active or inactive tasks" do&lt;br /&gt;  fixtures :projects, :tasks  &lt;br /&gt;  &lt;br /&gt;  setup do&lt;br /&gt;    @project = projects :project_with_task&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  specify "should filter out active tasks" do&lt;br /&gt;    active_tasks = @project.active_tasks&lt;br /&gt;       &lt;br /&gt;    active_tasks.size.should_be_eql 2&lt;br /&gt;    active_tasks.each {|t| t.status.should_be_eql 'active'}&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;When I ran the specification for the first time, I had:&lt;br /&gt;“undefined method &lt;i&gt;active_tasks&lt;/i&gt; for #&lt;Project:0x368ae04&gt;”&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;... investigation&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I didn’t expect that. I mean many people commented on this blog entry but nobody mentioned something about that. Well, I didn’t know what I am doing wrong (I still don’t know what I am doing wrong) but I did a quick search for more on ‘class_eval’ and found this blog entry: &lt;a href="http://neeraj.name/2007/01/31/ruby-class_eval-in-detail/"&gt;http://neeraj.name/2007/01/31/ruby-class_eval-in-detail/&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This example from that blog led me think that I need the class object, since the &lt;i&gt;class_eval&lt;/i&gt; method starts with class object. This is excerpt form that blog:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def add_method(obj)  &lt;br /&gt;  # Get the class of the object.  &lt;br /&gt;  obj.class.class_eval do  &lt;br /&gt;    # Add a new method to the class.  &lt;br /&gt;    def to_string  &lt;br /&gt;      to_s  &lt;br /&gt;    end  &lt;br /&gt;  end  &lt;br /&gt;end &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;... action&lt;/b&gt;&lt;br /&gt;&lt;p&gt;So, I introduce clazz parameter to the module:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Module&lt;br /&gt;  def memoized_finder(clazz, name, conditions=nil)&lt;br /&gt;    clazz.class_eval &lt;&lt;-STR&lt;br /&gt;      def #{name}(reload=false)&lt;br /&gt;        @#{name} = nil if reload&lt;br /&gt;        @#{name} ||= find(:all, :conditions =&gt; #{conditions.inspect})&lt;br /&gt;      end&lt;br /&gt;    STR&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I had a failure again, but this time I had the method &lt;i&gt;active_tasks&lt;/i&gt; defined. The problem was that it didn’t recognize &lt;i&gt;find()&lt;/i&gt; method. This make me believe, that this module should be probably included in the Project class somehow, but I am not currently aware of how.&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;... revelation&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Anyway, the problem is not only that it can’t recognize &lt;i&gt;find&lt;/i&gt; method, but that the &lt;i&gt;find&lt;/i&gt; method should be executed on the Task class, which is from the other side of the has_many association. So, I passed this class as a parameter as well:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Module&lt;br /&gt;  def memoized_finder(clazz, name, conditions=nil, condition_class=nil)&lt;br /&gt;    condition_class ||= clazz&lt;br /&gt;    clazz.class_eval &lt;&lt;-STR&lt;br /&gt;      def #{name}(reload=false)&lt;br /&gt;        @#{name} = nil if reload&lt;br /&gt;        @#{name} ||= #{condition_class}.find(:all, :conditions =&gt; #{conditions.inspect})&lt;br /&gt;      end&lt;br /&gt;    STR&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Well, this time the specification executed property but didn’t meet the expectation, since the number of active task for this object were more than the expected ones. This was due to the fact that the method that was specified would’ve retrieved all of the active tasks for all projects and not only for the current one. Specifying the expected behavior first was beneficial again! Without this specification, I could’ve thought that I am done and I would’ve moved forwards. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;... modification&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;So, I have to send the id of the Project as part of the sql condition. Somebody had the same question from the blog comments - how to send the id of the Project object, since if you specify id in the association block code, this would not be the id of the Project object. The suggestion is to use escape character. The code should look like this:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Project &lt; ActiveRecord::Base&lt;br /&gt;  has_many :tasks do&lt;br /&gt;    memoized_finder Project, :active, "project_id = \#{id} AND status = 'active'", Task&lt;br /&gt;    memoized_finder Project, :inactive, " project_id = \#{id} AND status = 'inactive'", Task&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Well, this didn’t work since the expression \#{id} was evaluated in the condition to #{id}. This is because we have: #{conditions.inspect} in the eval_class method evaluation. I am not sure why we need the inspect method, but once I removed it, it start working. &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;b&gt;... actually&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I just want to mention here that I don’t use strings for defining the status of the tasks (or whatever my actual class is). Instead, I use enumeration through the “has_enumerated” rails plugging. I prefer to work with reference tables for things like those and avoid duplication in the code or in the database. So, I have additional class: &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class TaskStatus &lt; ActiveRecord::Base&lt;br /&gt;  acts_as_enumerated&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;... finally&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This changes the code in the Project class to: &lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Project &lt; ActiveRecord::Base&lt;br /&gt;  has_many   :tasks do&lt;br /&gt;    TaskStatus.find(:all).each do |status|&lt;br /&gt;       memoized_finder Project, status.name.downcase.pluralize , "project_id = \#{id} AND task_status_id = #{status.id}", Task&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;... epilogue&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;I am not sure this is the best solution but it is working for me and somebody else could find it useful. Otherwise, you can comment on how I can improve it. Thanks!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-117220775202705954?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2007/02/filtering-hasmany-association-in-rails.html' title='Filtering has_many Associations in Rails'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/117220775202705954/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=117220775202705954&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/117220775202705954'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/117220775202705954'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2007/02/filtering-hasmany-associations-in.html' title='Filtering has_many Associations in Rails'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-114905088345399192</id><published>2006-05-30T23:43:00.000-05:00</published><updated>2006-05-31T00:05:01.896-05:00</updated><title type='text'>Is Java Back in the Game!?</title><content type='html'>&lt;p&gt;Well, I don’t believe so. However, the JVM could have some chances. Let me step back a little after such a flaming introduction and present various and mostly unrelated points.&lt;/p&gt;&lt;b&gt;What is all about?&lt;/b&gt;&lt;br /&gt;&lt;p&gt;As many others in my situation for the last year or so, I have been working in the world of Java but daydreamed about exciting and shining worlds like Ruby or its enjoyable &lt;i&gt;"resort"&lt;/i&gt; Ruby on Rails. Although I have some &lt;a href="http://igorstoyanov.blogspot.com/2005/11/learning-ruby-and-ruby-on-rails.html"&gt;issues&lt;/a&gt; with some of the perception in that new world, most of the innovations started happing there because of the Rails explosion.&lt;/p&gt;&lt;b&gt;...is there any hope?&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Looking more and more in my old world, I started realizing that I, as well as many others would not be able to escape from it, at least not any time soon. Enterprise software development is more about politics and questionable higher level decisions than real values, passion about what you are doing and ability to &lt;a href="https://gettingreal.37signals.com/"&gt;"get real"&lt;/a&gt;.&lt;/p&gt;&lt;b&gt;...alternatives?&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://blogs.zdnet.com/Hinchcliffe/?p=27"&gt;WOA&lt;/a&gt;, REST and &lt;a href="http://www.innoq.com/blog/st/2006/05/25/are_web_services_becoming_web_services_again.html"&gt;“are web services become a web services again” &lt;/a&gt; look promisingly exciting. It is not so much about language and technologies, it is about new way of thinking, designing and using systems. Sure, there a lot of interesting innovation there, but most of it is overtaken by extremely complex specification and vendor implementation of “enterprise” tools and frameworks for generating unmanageable code that doesn’t work as expected.&lt;/p&gt;&lt;b&gt;… actually, it is even worse...&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Although there are some important battles that could be won, the overall war with the “old enterprise world” is not going well.  The hope is fading away even faster if   we combine the application world (stand alone applications) with the integration (service oriented) world where the wide spread opinion is that we need even more vendor tools that solve magically all our problems.&lt;/p&gt;&lt;b&gt;...!?!?!?!?!?!?!?!?!&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Well, the Ruby and ROR outburst was big and definitely started a (r)evolution:&lt;br /&gt;From a blog &lt;a href="http://www.blogger.com/comment.g?blogID=20633170&amp;postID=114570403669708554"&gt;comment&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;“Java community was so tied up with doing things the 'right' way. People won't change their way of thinking before something else comes up which shows them otherwise. So thanks to RoR for opening some blind eyes in the conservative community.”&lt;/i&gt;&lt;/p&gt;&lt;p&gt;However, Java enterprise world has grown too much to be overthrown too easily or fast enough. What is more, Ruby/Rails is a (r)evolution but it is still not powerful  enough:&lt;/p&gt; - &lt;i&gt;“My pet peeves with Rails were the same like most other people back then: i18n, oracle support, integration with web servers wasn't as simple as deploying a WAR file.”&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;- &lt;a href="http://railsexpress.de"&gt;From&lt;/a&gt; Rails performance tuning &lt;a href="http://railsexpress.de/blog/files/slides/rubyenrails2006.pdf"&gt;presentation&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;   “Ruby interpreter is sloooow:&lt;br /&gt;  Deeply rooted in 60’s technology:&lt;br /&gt;  • no byte code, no JIT, interprets ASTs directly&lt;br /&gt;  • doesn’t perform any code optimization at compile time&lt;br /&gt;  • GC performance is erratic&lt;br /&gt;&lt;br /&gt; Ruby’s GC collects and is garbage!&lt;br /&gt; Designed for batch scripts, not long running server apps&lt;br /&gt; • tries to minimize memory usage&lt;br /&gt; • simple mark and sweep algorithm&lt;br /&gt; • uses malloc to manage contiguous blocks of Ruby objects”&lt;br /&gt;&lt;/blockquote&gt; - From &lt;a href="http://laughingmeme.org/articles/2005/09/01/ruby-threads"&gt;“Ruby threads are week"&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt; • slow as hell, threads tend to die unexpectedly&lt;br /&gt;• documentation and sample code limited to a handful of pages in the Pickaxe (lack of people using should have been clue #1)&lt;br /&gt;• non-OO (in Ruby! an int in Ruby is an object!), all examples use code blocks, subclassing Thread can have unexpected (to me, with my Java threading biases)&lt;br /&gt;results&lt;br /&gt;•many core libraries, and more painfully (in that I lost several weeks of my life, and some hair) ActiveRecord aren't thread safe.”&lt;br /&gt;&lt;/blockquote&gt;     (Well, Hibernate session is not thread safe either but this is different story.)&lt;br /&gt;&lt;p&gt; While Ruby/Rails hit Java very badly (C# as well to some degree but rapidly increasing the pressure with C#-3), the JVM is holding almost indestructibly against Ruby VM and doing pretty well against CRL as well.&lt;/p&gt;&lt;p&gt;So, if Java/JVM world is still sustaining big hits from outside (even from .NET these days) can it sustain a (r)evolution from inside?&lt;/p&gt;&lt;b&gt;&lt;a href="http://rmh.blogs.com/weblog/2006/02/groovy_the_slee.html"&gt;...wakening the sleeping giant.&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;i&gt;“In many respects Groovy is the best combination of the Java platform and dynamic language design. Groovy has been quiet, but like a sleeping giant Groovy will awaken and effectively take over as the dominate dynamic programming language…..”&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I omitted the last part of the sentence &lt;i&gt; “…after it becomes a JCP standard.”&lt;/i&gt; because I disagree with that part. Although JCP standard could help with the adoption from the conservative corporate/enterprise world I think that standards can actually make Groovy worse. Anyway, it sounds exciting. Let see more.&lt;/p&gt;&lt;b&gt;&lt;a href="http://graemerocher.blogspot.com/2006/03/groovy-sleeping-giant-elaboration.html"&gt;Groovy: The Sleeping Giant, an Elaboration&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;At first look, &lt;b&gt;&lt;i&gt;Groovy looked to me as Ruby without the Perl with obvious Java perception&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;Sounds very attractive to me so let me take deeper look into the language:&lt;/p&gt;&lt;b&gt;Mix and match - interfacing with java and using the enormous amount of Java APIs and libraries directly.&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;i&gt;“But, it is there where Groovy's true strength lies in its ability to cleanly interface with Java.”&lt;/i&gt; Basically, we can use existing java classless dynamically, test or extend them directly in Groovy. This is one of the best features in Groovy. We can introduce Groovy incrementally on old/new projects or just for specific tasks like configuration, tests and so on. Actually, &lt;a href="http://www.blogger.com/post-edit.g?blogID=6178209&amp;amp;postID=114905088345399192"&gt;test&lt;/a&gt; are very compelling candidate to be written in Groovy:&lt;br /&gt;&lt;br /&gt;- faster feedback (removing the compilation step)&lt;br /&gt;- test code doesn’t have the same strict requirements as the application source code.&lt;br /&gt;- much more productive when doing exploratory testing or scripting behavior specifications of a system.&lt;br /&gt;- writing test in DSL is very appealing.&lt;/p&gt;&lt;p&gt;Another good feature here is the ability to extend interfaces. It is kind of nonsense for a dynamic language but it is very beneficial to provide Groovy implementation of existing Java interface and use the Groovy implementation in the java code.&lt;/p&gt;&lt;b&gt;Ability to create DSLs with Groovy.&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;i&gt;“In addition there are other, largely undocumented, reasons why Groovy has huge amounts of potential:&lt;/i&gt;&lt;/p&gt;&lt;i&gt; &lt;/i&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;Meta-programming&lt;/b&gt; - Groovy has the ability to inject methods, constructors, properties, fields, etc. into ANY java class at runtime. Most of what AOP is used for nowadays can be achieved with Groovy's Meta-programming capability. No byte-code manipulation a la AspectJ, this is awesomely powerful and in combination with Groovy's support for closures and builders it makes it possibly to create mini-DSLs&lt;/i&gt;&lt;/p&gt;&lt;i&gt; &lt;/i&gt;&lt;p&gt;&lt;i&gt;&lt;b&gt;Power Features&lt;/b&gt; - Although there has been a lot of argument about the optional parenthesis, and the optional semi-colons etc. There are very good reasons for these things being optional: For combining closures and method calls to allow builder syntax. Builders and closures are very powerful, especially when you consider you can pass the same closure to a multiple different builders. Why you say? Well one may output a tree structure as XML another might render a GUI from it, I'll leave the rest to your imagination.”&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;“… the rest to your imagination”&lt;/i&gt;. Ruby does have similar features, but this is one of the first things that I looked for in Groovy. Ability to create DSLs is actually the real power of Ruby and it looks that Groovy can do it too.&lt;/p&gt;&lt;b&gt;... is that all?&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Of course not, but these are the most compelling features that made me look even deeper into the language. There is a lot more at the Groovy web site. Especially impressive (at least for a Java guy) are:&lt;br /&gt;- &lt;a href="http://grails.codehaus.org/GORM"&gt;Grails Object Relational Mapping (GORM)&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://groovy.codehaus.org/Groovy+SQL"&gt;Groovy SQL&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://groovy.codehaus.org/GPath"&gt;GPath&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://groovy.codehaus.org/GroovyMarkup"&gt;Groovy Markup&lt;/a&gt;&lt;br /&gt;- &lt;a href="http://groovy.codehaus.org/Groovy+SOAP"&gt;Groovy SOAP&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;b&gt;This is it!&lt;/b&gt;&lt;br /&gt;&lt;p&gt;I feel very excited and I think I like the name Groovy a lot. I am going to play around with Grovy. The most obvious choice is to start with &lt;a href="http://grails.codehaus.org/Quick+Start"&gt;Quick Start&lt;/a&gt; from &lt;a href="http://grails.codehaus.org/"&gt;Grails framework&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Grails is inspired by Ruby on Rails and built with Groovy. From the &lt;a href="http://docs.codehaus.org/download/attachments/29671/J1_2006_Grails_PowerPoint_v1.ppt"&gt;Grails presentations&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;Why Groovy?&lt;br /&gt;- Meta-Programming&lt;br /&gt;- Closure Support&lt;br /&gt;- Syntactically Expressive&lt;br /&gt;- Java Integration&lt;br /&gt;&lt;br /&gt;Built on very compelling and solid foundation:&lt;br /&gt;- Spring IoC, MVC and WebFlow&lt;br /&gt;- Hibernate&lt;br /&gt;- SiteMesh&lt;br /&gt;&lt;/blockquote&gt; &lt;p&gt;Are you familiar with these frameworks? Me too!&lt;br /&gt;&lt;br /&gt;When working with Grails, you don’t understand that these frameworks are there but if you want more flexibility (configuration), you can always use them directly.&lt;/p&gt;&lt;b&gt;The reality...&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Downloaded the framework, set up a home variable and I am ready to go.&lt;/p&gt;&lt;b&gt;… the build.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;u&gt;Positives:&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;- It is working as expected (as in RoR).&lt;br /&gt;&gt; grails create-app&lt;br /&gt;&lt;br /&gt;create-app:&lt;br /&gt;&lt;br /&gt;[input] Enter application name:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;u&gt;Negatives:&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;- Ant! This was great a few years ago but it is now clear that xml is not the best way to write build files. Groovy could’ve eaten its own dog food and create something similar to Rake (probably something like GrAnt!? It is not too late though.).&lt;br /&gt;&lt;br /&gt;- I can’t specify the name of the application directly instead, I have to wait to enter it.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;... the domain. Oooh, this could take a while.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;u&gt;Positives:&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;b&gt;1. I can optionally define property types in a domain class:&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;class Book {&lt;br /&gt;@Property Long id&lt;br /&gt;@Property Long version&lt;br /&gt;@Property String title&lt;br /&gt;      @Property String author&lt;br /&gt;}&lt;br /&gt;&lt;p&gt;The @Property thing is not the best way to do it but I can live with that when I have the options to define types for domain object properties.&lt;/p&gt;&lt;p&gt;Why the option to define Types is so important to me?&lt;br /&gt;This is something that is not possible in Ruby and it is interesting to explore whether it could be beneficial in Groovy in some way.&lt;/p&gt; &lt;p&gt;1.1.)  Domain Driven Design&lt;/p&gt;&lt;p&gt;This allows frameworks like Grails to use an approach where everything is driven by the application - you create the domain class first and then Grails will create the different database objects.&lt;/p&gt;This is absolutely the opposite of the RoR approach where you are leveraging an existing database object and creating the domain class on top of it. One of the reasons is that you can’t optionally specify types in Ruby. Since the current relation databases work with types, the only choice is to go from the stricter to the more loosely couple system, or db-to-ruby. Well, this is an issue only if you don’t fill comfortable defining your domain model in a database schema.&lt;br /&gt;&lt;p&gt;It is still an issue at least for me but I believe that the second point is relevant for almost everybody.&lt;/p&gt; &lt;p&gt;1.2.) Powerfull IDEs and refactoring&lt;br /&gt;&lt;br /&gt;&lt;i&gt;“The fact remains there are still huge benefits to compiled languages such as Java especially in large systems where the benefit of refactoring and powerful IDEs becomes clear.”&lt;/i&gt;&lt;/p&gt;I am not very sure for the compiled languages but the refactoring and powerful IDE do matter enormously.  Unfortunately, you have to give up on this for dynamic languages. There is really impressive progress with IDE’s like RedRails. However, the dynamic nature of the language constraints a lot what such IDEs can do. The problem is that a tool or many times, even a person can’t figure out what is the type of a variable.&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;class Song{&lt;br /&gt;length&lt;br /&gt;name&lt;br /&gt;author&lt;br /&gt;}&lt;br /&gt;&lt;p&gt;Is the “length” a string or an integer? Is the name a string or is a type Name? Many times, you don’t need to know but some times it would’ve been nice to know. What about if you can mix statically typed with dynamically typed? What about if we have the option to specify a type if we feel like doing it? Do we get the best from the both worlds? I don’t know but we can do that in Groovy:&lt;/p&gt;class Song{&lt;br /&gt;Integer length&lt;br /&gt;String  name&lt;br /&gt;Author  author&lt;br /&gt;}&lt;br /&gt;&lt;p&gt;The option to declare the type (at least in our domain objects) can bring the power of IDEs (refactoring, auto completion and so on…) into dynamic languages.&lt;/p&gt;&lt;i&gt;&lt;b&gt;2. Domain objects don’t extend any base framework object.&lt;/b&gt;&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&lt;u&gt;Positives:&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;&lt;p&gt;This one is so obvious by itself that I am not sure what to add more.&lt;/p&gt;&lt;i&gt;&lt;u&gt;Negatives:&lt;/u&gt;&lt;/i&gt;&lt;br /&gt;&lt;p&gt;2.1.) Grails generated toString, hashCode and equals method as well as id and version property. The method basically uses only the id property in an object.&lt;br /&gt;This is good to have but the problem with generation is that you have to maintain afterwards and usually this is clear indicator of typical code smells. Let say that I generate 20 domain objects, all of them has the same three generated method as well as id and version property. Let say I use a lot of caching and I have problems with stale data and uniqueness of objects. I see the version property in the objects and decide that the id plus the version number define the uniqueness of an object. Oh, boy… I have to go and copy and paste the three methods with included version property to all 20 classes.&lt;/p&gt;&lt;p&gt;One way to refactor this is to have base object, something like “IdentifiableObject” where we can define the id and version property as well as the three methods defined above. I know that the framework creators don’t want to create bad association with having base objects but the difference here is that the base object is not part of a framework.&lt;/p&gt;&lt;p&gt;Having a base object like that could be beneficial in situation (I have encountered very often) when you want to perform an operation to all entity objects (identifiable objects) and disregard the value objects (entity and value definition according to Domain Driven Design book).&lt;/p&gt;&lt;p&gt;2.2.) Another negative was that there was a unit test generated but it was empty. I didn’t see test for the three generated methods mentioned above!?&lt;/p&gt;&lt;b&gt;controllers:&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Is there anything to be said after I saw this?&lt;/p&gt;class BookController {&lt;br /&gt;@Property scaffold = true&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;which auto-generated at runtime the necessary actions and views:&lt;br /&gt;• list&lt;br /&gt;• show&lt;br /&gt;• edit&lt;br /&gt;• delete&lt;br /&gt;• create&lt;br /&gt;• save&lt;br /&gt;• update&lt;br /&gt;&lt;p&gt;I don’t know if you spotted but the controller again doesn’t need to extend a framework base class. Good to mention here that you can inject services in the controller (through Spring although you don’t understand this) just with using naming conventions.&lt;/p&gt;&lt;b&gt;view.&lt;/b&gt;&lt;br /&gt;&lt;p&gt;The view is similar to RoR but without the scripting code inside. Everything is a proper xml which is very nice. On a different topic, I would much prefer something like Google Web Toolkit at this point but this is different story.&lt;/p&gt;&lt;b&gt;….conclusion.&lt;/b&gt;&lt;br /&gt;&lt;p&gt;There are lots of nice things in Groovy or Grails but there are many not so nice too. A short list (but very critical) includes: not very good error messages, currently not debugging support, not IDE support (…yes, there is something there but at least for Eclipse the plugging is far for even reasonable solution).&lt;/p&gt;&lt;p&gt;All these issues could be resolved but the biggest issue for me is that there is still no well defined community with clear vision and commitment behind Groovy. One example is that I tried to look for mixins in Groovy (a very important feature for me) but the only thing that I found is a proposal to include them in the language and nothing else.&lt;/p&gt;&lt;p&gt;Despite that and the fact that some frameworks integrate already with Groovy including Spring 2.0, RIFE, NanoContainer, and Drool, I am cautiously optimistic about Groovy and Grails and I will continue my further exploration.&lt;/p&gt;&lt;p&gt;For the two people left that still reading this long post, do you file like &lt;i&gt;&lt;b&gt;Grooving&lt;/b&gt;&lt;/i&gt;?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-114905088345399192?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2006/05/is-java-back-in-game.html' title='Is Java Back in the Game!?'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/114905088345399192/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=114905088345399192&amp;isPopup=true' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114905088345399192'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114905088345399192'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2006/05/is-java-back-in-game.html' title='Is Java Back in the Game!?'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-114893419534268515</id><published>2006-05-29T15:17:00.000-05:00</published><updated>2006-05-29T15:25:35.746-05:00</updated><title type='text'>How do you keep the build time low?</title><content type='html'>I was reading: &lt;a href="http://jroller.com/page/peter_pilgrim?entry=my_javaone_2006_conference_second1"&gt;http://jroller.com/page/peter_pilgrim?entry=my_javaone_2006_conference_second1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;where Rod Johnson was quoted:&lt;br /&gt;&lt;blockquote&gt;“It is possible to write unit test for applications in J2EE that run under five minutes. If your unit test take place longer than this, then it is wrong.”&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I little more relax time is stated in Martin Fowler's Continuous Integration &lt;a href="http://www.martinfowler.com/articles/continuousIntegration.html"&gt;article&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;“For most projects, however, the XP guideline of a ten minute build is perfectly within reason. Most of our modern projects achieve this. It's worth putting in concentrated effort to make it happen, because every minute you reduce off the build time is a minute saved for each developer every time they commit. Since CI demands frequent commits, this adds up to a lot of time. “&lt;/blockquote&gt;&lt;br /&gt;I completely agree with both of them although I would prefer the five minute constrain. Slow builds could have huge impact on the productivity of an Agile/XP team. Some of the reasons for slow build times are if we use database fixtures (as the accepted practices in RoR) or if we don’t bother to use stabs/mocks when appropriate in our test. All of that could be disregarded by many as unnecessary complication but from my previous experience on various projects using db fixtures or not using stabs/mocks have been an issue at some point or another.&lt;br /&gt;&lt;br /&gt;An example is the fact that the build for my current project that has been continuing for the last year and a half, on average 6-8 developers, more that 1000 classes, about 100 domain objects with up to 83% unit test coverage (at times :-)) is taking just a little more that 4 min and about 1 min of that is xdoclet generation. The real time is 3 min!!! It is not even a pure unit test build. Our build includes testing the persistence for all domain objects with the database that would be in production as well as the instantiation of Spring IoC container inside the unit tests.&lt;br /&gt;&lt;br /&gt;In the beginning we didn’t use stubs/mocks and everything was “freely” accessing the database. After the second month of the project, the build (probably about 20-25% of the current size of the project) was taking already more than 4 min! I have seen/heard about many projects where the unit test build is taking from 30 -1.30 min. I strongly believe that built times like that are unacceptable for an XP team.&lt;br /&gt;&lt;br /&gt;I haven’t had the chance to use RoR on something more than a personal learning projects and I wonder how much time is a build taking on an average enterprise project using RoR or how do you overcome this potential problem in RoR projects?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-114893419534268515?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2006/05/how-do-you-keep-build-time-low.html' title='How do you keep the build time low?'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/114893419534268515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=114893419534268515&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114893419534268515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114893419534268515'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2006/05/how-do-you-keep-build-time-low.html' title='How do you keep the build time low?'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-114084464708352881</id><published>2006-02-24T23:15:00.000-06:00</published><updated>2006-02-24T23:24:47.366-06:00</updated><title type='text'>Leverage Application Framework Integration with Spring</title><content type='html'>&lt;div&gt;&lt;i&gt;Written by: &lt;/i&gt;&lt;b&gt;&lt;a href="http://www.igorstoyanov.blogspot.com/"&gt;Igor Stoyanov&lt;/a&gt;&lt;/b&gt; and &lt;b&gt;&lt;a href="http://micro-workflow.com/"&gt;Dragos Manolescu&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;&lt;b&gt;ABSTRACT&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This article summarizes our experience in simplifying application frameworks integration using Spring framework as well as provides some overview of Spring framework. We will try to show that Spring is a powerful framework, which helps you build a loosely coupled flexible architecture. It helps in decoupling components and greatly simplifies a software project. By using more pragmatic approach, Spring can boost considerably developers productivity and efficiency. In very simple and elegant way, Spring framework can address most infrastructure concerns of typical applications.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;b&gt;KEY POINTS&lt;/b&gt;&lt;br /&gt;Spring Framework provides:&lt;br /&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li style="color: black; line-height: 12pt;"&gt;ability to build loosely coupled architecture&lt;/li&gt; &lt;li style="color: black; line-height: 12pt;"&gt;simplify application development&lt;/li&gt; &lt;li style="color: black; line-height: 12pt;"&gt;leverage application framework integration&lt;/li&gt; &lt;li style="color: black; line-height: 12pt;"&gt;reduce complexity&lt;/li&gt; &lt;li style="color: black; line-height: 12pt;"&gt;improve testing&lt;/li&gt;&lt;/ul&gt;&lt;b&gt;STRUCTURE OF ARTICLE&lt;/b&gt;&lt;br /&gt;&lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li&gt;&lt;b&gt;Intro: &lt;/b&gt;Common problems across many applications provided fertile grounds for software reuse. Using frameworks can help solve these problems and give you better productivity&lt;br /&gt;and helps developers focus on solving business problem to deliver more business value to customers.&lt;/li&gt; &lt;li&gt;&lt;b&gt;Spring Overview: &lt;/b&gt;Introduction to most important feature of Spring relevant to framework integration and reducing complexity of an application.&lt;/li&gt; &lt;li&gt;&lt;b&gt;Using Spring Framework Integration: &lt;/b&gt;Greatly simplifies the integration of independently-developed frameworks within a single application. Spring reduce complexity by coding against interfaces and not depending on application servers.&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Intro&lt;/h2&gt;&lt;p&gt;Building business applications entails solving two types of problems. Some of these problems are unique to each application. For example, a health care management system catering to teachers has to accommodate coverage periods that span over an academic year rather than the typical calendar year. It also has to accommodate plans negotiated at the school district rather than at the employer level. These characteristics make it different than the typical heath care management system.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Other problems are common across many applications. For example, applications that have a presentation component must deal with user interaction. Applications that store objects into a relational database must deal with object-relational mapping. And so on.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The problems common across many applications provided fertile grounds for software reuse. Code reuse techniques such as class libraries and frameworks already provide the building blocks for many recurring problems. Their availability shortens development times and helps developers focus their energy on the unique aspects of their applications.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;As the software platforms such as J2EE and .NET mature, the number of frameworks available for them increases. Frameworks represent skeleton applications that tackle specific problems. Examples include (in no particular order) application integration frameworks; common services frameworks; messaging frameworks; application architecture frameworks; connection frameworks; reference data frameworks; persistence frameworks; logging frameworks; caching frameworks; authorization frameworks; portal frameworks; rules management frameworks; optimization frameworks; business process management frameworks; data management frameworks; presentation layer frameworks; and so on.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With an increasing choice of available frameworks developers face the problem of using more than one framework in their applications, each of which addresses a specific problem. However integrating many frameworks while following good design practices and maintaining consistency is challenging. So how do you build applications that combine several frameworks?&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Lightweight Containers&lt;/h2&gt;&lt;p&gt;Since frameworks provide large scale reuse, their usage typically affects the application’s structure (i.e., it has architectural impact). Until recently developers had limited options for providing integration among objects and frameworks within their application. In J2EE the only framework that partially addressed some of these issues was the Enterprise Java Beans (EJB) specification. For several years EJB represented the only framework for managing application tier objects.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The specification covered many nice features, such as declarative transaction in container management of business objects. However the difficulties related to managing and testing business transactions as well as other problems caused the emergence of alternatives: the lightweight containers.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;These lightweight containers take some of the successful ideas from EJB to bring a greater level of sophistication to non-EJB architectures. They are similar to EJB architectures in being centered on a layer of managed business service object. However, this is where the similarity ends. Instead of running inside an EJB container, business objects run inside a lightweight container. Lightweight containers manage the business objects as Plain Old Java Objects (POJO) running within the container.The most popular lightweight containers are &lt;a href="http://www.springframework.org/"&gt;Spring framework&lt;/a&gt;, &lt;a href="http://www.picocontainer.org/"&gt;Pico container&lt;/a&gt; and &lt;a href="http://jakarta.apache.org/hivemind/"&gt;HiveMind&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Lightweight containers employ Aspect Oriented Programming (AOP) interception to deliver enterprise services. For example, we can have a business service implemented as POJO that doesn’t have the responsibility to perform transaction management.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;class EmployerService {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;public Collection findAllEmployers(){}&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;public void save(Employer employer){}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Then we can declare the methods of the service to be intercepted via AOP and be transaction managed. A configuration file will look like this:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;bean id="transactional-employer-service" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="transactionManager"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref local="transactionManager"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;bean class="EmployerService"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="transactionAttributes"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="save*"&gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;/props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;We can define different transaction mangers for the &lt;span style=";font-size:85%;color:blue;"  &gt;"transactionManager"&lt;/span&gt; property in &lt;span style=";font-size:85%;color:blue;"  &gt;"TransactionProxyFactoryBean"&lt;/span&gt; without any changes to our &lt;span style=";font-size:85%;color:blue;"  &gt;"EmployerService"&lt;/span&gt; class as well as define the transaction propagation strategy for the different methods in the same class.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Unlike EJBs, service objects managed by lightweight containers don’t usually need to depend on container APIs, meaning that they don’t need to inherit from a specific framework class. This makes the (re)usable outside of the container, which in turn greatly simplifies testing and improves reusability. If transaction management is the only requirement then implementing service objects as POJO may not appear as a real advantage. However, it becomes incredibly beneficial once the application developers bring in frameworks for security, persistence, and remoting, to name just a few.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Spring Overview&lt;/h2&gt;&lt;p&gt;Spring is an open source framework for managing business objects. It provides integration of the middle layer of an application’s components. Spring relies on two ideas for achieving this integration: &lt;b&gt;Inversion of Control (IoC)&lt;/b&gt; and &lt;b&gt;Dependency Injection(DI).&lt;/b&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Inversion of Control removes the responsibility of looking up resources or services from the business objects, and places it to the container. Instead of making a library call, an IoC container like Spring injects the needed resources or services into the domain objects. This Inversion of Control with dependency injections addresses the problem of wiring an application’s layers in a loosely coupled manner.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;img src="http://www.geocities.com/igorstoyanov/spring_architecture.gif" height="831" width="579" /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One possible solution to the above problem relies on a Service Locator that hides the underlying container. This solution achieves the look up service with Inversion of Control. Service Locator pattern implements IoC with &lt;i&gt;Dependency Lookup&lt;/i&gt;. For example:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;public void SomeBusinessObject{&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;DataSource dataSource;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;public SomeBusinessObject(){&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;dataSource = ServiceLocator.lookup("java:comp/env/jdbc/MyDataSource");&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In contrast, Spring provides Inversion of Control through &lt;i&gt;Dependency Injections&lt;/i&gt;. This solution is typical of the Spring framework.Injecting a resource or service into our business objects requires either setter methods (for setter injection) or constructor (for constructor injections). The following example demonstrates the latter:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;public void SomeBusinessObject{&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;DataSource dataSource;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;public SomeBusinessObject (DataSource dataSource){&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;this.dataSource = dataSource;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The Spring configuration file defines the actual data source:&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&amp;lt;bean id="jdbcDataSource"   class="org.springframework.jndi.JndiObjectFactoryBean"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="jndiname"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;value&gt;java:comp/env/jdbc/MyDataSource&amp;lt;/value&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="someBusinesObject" class="SomeBusinessObject"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;constructor-arg&amp;gt;&amp;lt;ref bean="jdbcDataSource"/&amp;gt;&amp;lt;/constructor-arg&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;When Spring first initializes the object this configuration injects "jdbcDataSource" into the business object.&lt;/p&gt;&lt;p&gt;Spring uses application context objects to handle the location and configuration of resources such as Session Factories, JDBC data sources, and other related resources, as well as inter-object dependencies. This makes these values easy to manage and change. Dependency injection and interface implementation allow us to lower the coupling between different architectural layers. For example, this provides a mechanism for injecting mocked services or recourses for testing. As a whole, Inversion of Control with Dependency Injections solve very elegantly all problems related provides a simple and consistent approach in handling configurations as well as lowers the complexity of all other application layers.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Another very important feature that Spring provides is Declarative Transaction.  Spring's declarative transaction demarcation can be applied to any POJO target object. The choices for a back-end transaction manager range from simple JDBC-based transactions to full-fledged J2EE transactions via JTA. The application service interfaces and their implementations are not dependent on Spring or Spring transaction management in particular.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The Spring framework provides fine grained transaction management and flexibility in specifying transaction strategy. During runtime, Spring frameworks intercepts (via AOP-like interceptors) calls to service methods manage the transactions according to the declared transactional properties of the service methods. For example, in the above EmployerService example we declare transaction propagation for the two methods:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&amp;lt;property name="transactionAttributes"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;prop key="save*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;prop key="*"&amp;gt;PROPAGATION_REQUIRED,readOnly&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/props&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The second declaration (which includes the "readOnly" qualifier) marks a retrieval operation, when a business transaction doesn't need to be committed or rollbacked. Spring supports additional transaction strategies and can apply them not only at the method level but also to a group of methods or classes.&lt;/p&gt;&lt;p&gt;Inversion of Control with Dependency Injection and support for Declarative Transaction are Spring framework features that can greatly reduce the complexity of integrating different application layers as well as fosters better OO design and greatly improves testability. Let’s look in more details at some of the key benefits of building applications with Spring.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Using Spring for Framework Integration&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;For the past twelve months, we have been building a large enterprise Java application. We used Spring to integrate Hibernate (ORM framework), Tapestry (component based MVC web framework) and Acegi (security framework). Let’s take a closer look at using Spring for integrating independently-developed frameworks with the same application.&lt;br /&gt;&lt;/p&gt;&lt;b&gt;&lt;i&gt;-  O/R mapping integration&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Spring framework supports integration with variety of O/R mapping frameworks. Out of the box Spring integrates directly with JDBC or ORM solutions like Hibernate, JDO, TopLink, and iBatis. In fact, the Spring data access architecture allows it to integrate with any underlying data access technology. Spring and Hibernate are a particularly popular combination.&lt;/p&gt;&lt;p&gt;For the implementation of our DAO layer, we used Hibernate framework as well. Spring provides integration with it in the following ways:&lt;/p&gt;&lt;ol style="margin-top: 0in;"&gt;&lt;li&gt;&lt;p&gt;Spring offers easy, efficient and safe handling of units of work such as Hibernate Session. Generally, ORM frameworks use the same "Session" object for efficiency and proper transaction handling. Spring can transparently create and bind a session to the current thread, using either a declarative AOP method interceptor approach, or by using an explicit "template" wrapper class at the Java code level. Thus Spring solves many of the usage issues that affect many users of ORM technology.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;  We used Spring to provide an abstraction around the Hibernate "Session" objects, thus  wrapping the session in the form of one line helper method - getHibernateTemplate(). Since Hibernate Session is implementation of Unit of Work pattern, it needs to use the same Session object for efficiency and proper transaction handling. Spring provide thread safe access to this Session object by putting in it on ThreadLocal.&lt;br /&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Spring provides resource lookup and allocation for DAO. Spring intercepts the creation of DAO implementation objects at the application start up and injects Hibernate session into DAO. Example configuration will look like that:&lt;br /&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;  &amp;lt;bean id="exampleDAO" class="ExampleHibernateDAO&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="sessionFactory"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref local="hibernateSessionFactory"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;  Hibernate session is injected into ExampleHibernatedDAO object when created. This removes from the object the burden to know how to look up for any resources that it needs.&lt;br /&gt;&lt;/p&gt; &lt;/li&gt; &lt;li&gt;Spring wraps exceptions from the Hibernate layer, converting them from proprietary (possibly checked) exceptions, to a set of abstracted runtime exceptions. This allows developers to handle most persistence exceptions (which are non-recoverable) only in the appropriate layers, without annoying boilerplate catches/throws, and exception declarations. For example, using Hibernate directly will result in code like this:&lt;br /&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;  public void save(Object obj) {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;try {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;Session session = SessionManager.currentSession();&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;Transaction tx = session.beginTransaction();&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;session.save(obj);&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;tx.commit();&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;session.close();&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;} catch (HibernateException e) {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;log.error("Save failed.");&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;} finally {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;try {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;SessionManager.closeSession();&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;} catch (HibernateException e1) {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;log.error("Problem closing session");&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;}&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;}&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Spring on the other hand wraps all of the exception handling as well as the transaction operation in one line method invocation. The above example using Spring will look like:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;public void save(Object obj) {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;getHibernateTemplate().saveO(obj);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can still trap and handle exceptions anywhere you need to but they are nicely wrapped.&lt;br /&gt;&lt;/p&gt; &lt;/li&gt;&lt;/ol&gt;&lt;b&gt;&lt;i&gt;- Service layer Integrations&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;The service layer benefited the most from Spring:&lt;br /&gt;&lt;/p&gt;&lt;ol style="margin-top: 0in;"&gt;&lt;li&gt;&lt;p&gt;Spring provided transaction management for business objects. Our service objects are stateless. However, very often services access shared resources as Hibernate Session. Thus we had the ability to configure the service object with either declarative transaction management, AOP method interceptor, or an explicit 'template' wrapper class at the Java code level. Spring provides seamless framework support for any of the solution above. However, we used only declarative transaction since this approach was sufficient for all services in our project.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt; &lt;li&gt;&lt;p&gt;Spring injected DAO and other business resources into service objects. We employed dependency injection when we needed particular business object or resource. Consequently our development team did not have to implement the Service Locator Pattern in order to request a particular service.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt; &lt;li&gt;&lt;p&gt;Spring encouraged coding against interfaces. Using this basic OO principle yielded a pluggable design. This allowed developers to mock or stub service objects during unit testing.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt; &lt;li&gt;Spring provided an alternative to implementing service as Singletons. The proliferation of Singletons reduces testability and causes lots of other problems. In addition, implementing a multi-threaded Singleton is more complex than the single-threaded GoF implementation. Spring provides thread safety through the use ThreadLocal. By default, all bean declared in Spring configuration files are singletons.&lt;br /&gt;&lt;p&gt;  The following example shows our use of declarative transaction management, dependency injections of DAO, and coding against interfaces for a service. It also instantiates the service as a singleton:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;   &amp;lt;bean id="transactionManager" singleton="true" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="sessionFactory"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref bean="hibernateSessionFactory"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="transactionProxyTemplate" abstract="true" singleton="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="transactionManager"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref local="transactionManager"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="transactionAttributes"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="update*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="set*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="store*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="*"&amp;gt;PROPAGATION_REQUIRED,readOnly&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;/props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="transactionalExampleService" parent="transactionProxyTemplate" singleton="true"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;bean class="ExampleService"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;property name="exampleDAO"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="80" /&gt;&amp;lt;ref bean="hibernateExampleDao"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;This bean factory configuration files specifies the following:&lt;br /&gt;&lt;/p&gt;  &lt;ul style="margin-top: 0in;" type="disc"&gt;&lt;li&gt;&lt;p&gt;Spring will create as singletons all of the above beans, excluding the abstract "transactionProxyTemplate".&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;   &lt;li&gt;&lt;p&gt;Spring intercepts the creation of "transactionManager" object and injects the bean declared with name "hibernateSessionFactory".&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;   &lt;li&gt;&lt;p&gt;The abstract class declaration of "transactionProxyTemplate" class provides declarative transaction management for all children object methods starting with declared prefix name. For example, assume a bean declared as a child of  "transactionProxyTemplate". If this child object has method name starting with "store..." then it is guaranteed that it will be provided read and write transaction management during invocation of this method as well as thread safe access to all common resources that this method or any other nested object methods work with.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;   &lt;li&gt;&lt;p&gt;Spring also intercepts the creation of "transactionalExampleService". The implementation of this object is "ExampleService.class". This object has "transactionProxyTemplate" as a parent, which means that it inherits all properties and transaction management declared in the parent. Also, a bean declared with name "hibernateExampleDao" would be injected via setter method at the creation time.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;  &lt;/ul&gt; &lt;/li&gt;&lt;/ol&gt;&lt;b&gt;&lt;i&gt;- Application/Façade layer integration&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;We didn’t really need Spring here for anything but integration. We used Spring to inject the services into facade objects. Since our façade objects kept the state of the current user progress, they hat to be instantiated as new objects every time. In order to do that, we explicitly had to specify singleton property to be false. For example:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;bean id="facadeTemplate" abstract="true" class="BaseFacade"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="exampleService"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref bean="transactionalExampleService" /&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="exampleFacade" class="ExampleFacade"  parent="facadeTemplate" singleton="false" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In this configuration file, we have defined the bean "exampleFacade" to be created as a new object every time when it is requested by another object. Since the parent "facadeTemplate" has property with name "exampleService", an implementation object of ExampleService interface will be injected during creation time.&lt;br /&gt;&lt;/p&gt;&lt;b&gt;&lt;i&gt;- Tapestry Page Controllers integration&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;We needed the Spring context to access façade or service objects in our controllers. We used Spring as Service Locator /Lookup pattern in order to locate business objects. For example, accessing the façade objects would be wrapped the following way:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;SomeFacade façade = getBean(someServiceName);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The implementation of this method is the follows:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;protected Object getBean(final String beanName) {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;return getApplicationContext().getBean(beanName);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private ApplicationContext getApplicationContext() {&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;return (ApplicationContext) getFromGlobal(Engine.APPLICATION_CONTEXT_KEY);&lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which obtains the Spring context from the web server.Alternatively we could define services or resources declaratively. Fore example, the same can be achieved with the following declaration in Tapestry page specification file:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;property-specification name="someService" type="SomeService"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;global.appContext.getBean("someServiceName ")&lt;br /&gt;&amp;lt;/property-specification&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In addition to facilitating the integration of frameworks Spring also affects the complexity and testability. In closing let’s take a closer look at these qualities.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Other Benefits of Using Spring&lt;/h2&gt;&lt;b&gt;&lt;i&gt;- Reducing Complexity&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;Spring is both comprehensive and modular. Spring has a layered architecture, meaning that it can be chosen to use just about any part of it in isolation, yet its architecture is internally consistent. Since Spring is designed so that applications built with it depend on as few of its APIs as possible, most business objects in Spring applications have no dependency on Spring. Consequently all business objects can be implemented as POJO. In contrast, many other frameworks (including) require implementing some framework base classes. This introduces coupling between the domain and the infrastructure.&lt;/p&gt;&lt;p&gt;By using Spring framework, we were very successful in reducing overall complexity in our project. Spring greatly simplified the integration with Hibernated framework, as well as provided very consistent and straightforward way of using services or resources among the different application layers.&lt;br /&gt;&lt;/p&gt;&lt;b&gt;&lt;i&gt;- Improve Testing&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;p&gt;The use of POJO objects in Spring applications can run without modifications outside the container and thus are much easier to test. Spring's inversion of control approach makes it easy to swap implementations and locations of resources such as Hibernate session factories, datasources, transaction managers, and mapper object implementations (if needed). This facilitates isolating the area under test.&lt;/p&gt;&lt;p&gt;Our project we had a lot of business functionality related to historical data and effectively of this data. For this reason, in order to have reliable tests, we had to use different implementation of our TimeService interface. In tests, we overridden the default implementation and that allowed us to move the time according to a particular test needs. This is the default implementation:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&amp;lt;bean id="timeService" class=" TimeService"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Then in a different Spring configuration file, which is loaded only during testing we override the previous declaration:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;bean id="timeService" class=" TimeServiceStub"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Also, since our DAO weren’t transaction managed, we wired them for the test to be transactional. The application dao was declared as:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;bean id="hibernateExampleDao" class="ExampleDAOHibernate"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="sessionFactory"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref local="hibernateSessionFactory"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;and the bean used in tests looks like:&lt;br /&gt;&lt;span style=";font-size:85%;color:blue;"  &gt;&lt;br /&gt;&amp;lt;bean id="transactionalHibernateExampleDAO" parent="transactionalProxyTemplate"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="transactionAttributes"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="store*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="save*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="delete*"&amp;gt;PROPAGATION_REQUIRED&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="60" /&gt;&amp;lt;prop key="*"&amp;gt;PROPAGATION_REQUIRED,readOnly&amp;lt;/prop&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;/props&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;property name="target"&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="40" /&gt;&amp;lt;ref bean=" hibernateExampleDao"/&amp;gt;&lt;br /&gt;&lt;img src="http://www.geocities.com/igorstoyanov/dotclear.gif" height="1" width="20" /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt; - Vendor Independence&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Different server solutions have different performance and other characterizes, and there is no perfect one size fits for all solution. Alternatively, it may be found that certain functionality is just not suited to an implementation using a particular server. Thus it makes sense an application be decoupled from the vendor-specific implementations of container managed transactions and lookup resources. If there is ever a need to switch to another server implementation for reasons of functionality, performance, or any other concerns, using Spring now can make the eventual switch much easier.&lt;/p&gt;&lt;p&gt;However, most places seems to have already invested in a vendor’s stack and are not very likely to changed form one to another. Even in cases like that, since Spring is modular as well as free open source framework just about any part of it can be used and benefited. In our project Spring enable us with completely portable solution. The production environment, user acceptance and quality insurance testing were done on WebSphere application server. However, the developers of the team developed and tested on very light web server - Jetty.  This saved a lot of time of deployment and configuration during development.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Another very important benefit was that by using Jetty server together with Tapestry frameworks, we were able to see the changes on the screen immediately after refresh without any redeployment. Spring provided out of container transaction management declarative authentication with Acegi Security framework integrated with Spring, database connection pooling, property configuration manager. All of them were integrated by Spring out of the application server container.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Summary&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Spring is a powerful framework, which helps you build a loosely coupled flexible architecture. It helps in decoupling and greatly simplifies a software project development by removing dependency on the complex specification of application servers. By using more pragmatic approach, Spring can boost considerably developers productivity and efficiency. It can address in very simple and elegant way most infrastructure concerns of typical applications as well as allows you to seamlessly integrate with other framework used in a project.&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;Acknowledgements&lt;/h2&gt;&lt;p&gt;I would like to thank to &lt;b&gt;&lt;a href="http://micro-workflow.com/"&gt;Dragos Manolescu&lt;/a&gt;&lt;/b&gt;, an enterprise architect at &lt;a href="http://www.thoughtworks.com/"&gt;ThoughtWorks&lt;/a&gt;, for his great help and contributions to this article. Without his consistent guidelines I wouldn't be able to put it together.&lt;/p&gt;&lt;h2&gt;Reference&lt;br /&gt;&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Dragos Manolescu,&lt;/b&gt; Framework Abuse: &lt;a href="http://micro-workflow.com/node/4"&gt;http://micro-workflow.com/node/4&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;b&gt;Martin Fowler&lt;/b&gt;, Dependency Injection: &lt;a href="http://www.martinfowler.com/articles/injection.html"&gt;http://www.martinfowler.com/articles/injection.html&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;b&gt;Rod Johnson&lt;/b&gt;, Expert One-on-One J2EE Design and Development (Programmer to Programmer), 2002&lt;/li&gt; &lt;li&gt;&lt;b&gt;Rod Johnson&lt;/b&gt;, Expert One-on-One J2EE Development without EJB, 2004&lt;/li&gt; &lt;li&gt;&lt;b&gt;Spring framework&lt;/b&gt;: &lt;a href="http://www.springframework.org/"&gt;http://www.springframework.org&lt;/a&gt;&lt;/li&gt; &lt;li&gt;&lt;b&gt;Spring AOP&lt;/b&gt;: &lt;a href="http://www.springframework.org/docs/reference/aop.html"&gt;http://www.springframework.org/docs/reference/aop.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-114084464708352881?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2006/02/leverage-application-framework_24.html' title='Leverage Application Framework Integration with Spring'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/114084464708352881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=114084464708352881&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114084464708352881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/114084464708352881'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2006/02/leverage-application-framework_24.html' title='Leverage Application Framework Integration with Spring'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113928747594141988</id><published>2006-02-06T22:38:00.000-06:00</published><updated>2006-05-19T12:43:06.186-05:00</updated><title type='text'>Are there bugs in agile project?</title><content type='html'>&lt;i&gt;&lt;span style="font-weight: bold;"&gt;(Updated)&lt;/span&gt;&lt;br /&gt;"The main aim of XP is to lower the cost of change."&lt;/i&gt;&lt;br /&gt;&lt;p&gt;In many agile projects, one of the most difficult questions is how to deal with defects when they weren’t supposed to exist at all.&lt;/p&gt;&lt;h4&gt;Different types of defects...&lt;/h4&gt;There are two broad categories of defects - implementation defects and requirements defects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;implementation defects refer to defects in architecture, design, coding, installation, or any other aspect of the technical implementation of a software development project. Implementation defects are a major source of project trouble in traditional methodologies but no so much in agile practices.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;requirements defects include all types of requirements, functional or story card specifications, acceptance testing (probably FIT) and any other means to define what the software is supposed to do and, from a functional perspective, how it is supposed to do it. Requirements defects are very relevant for "building the right software" and as such they are the most disastrous and costly.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;The best we can do...&lt;/h4&gt;Agile development practices are sometimes thought of as an undisciplined approach to software development, lacking such things as effective defect management. On the contrary, agile development does much to reduce the incidence of defects in the first place:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;we have all types of automated tests - unit, integration, regression, functional, acceptance and so on.&lt;/li&gt; &lt;li&gt;we do TDD to have very fast feedback and to ensure that the code is thoroughly tested.&lt;/li&gt;  &lt;li&gt;when we pair we have the benefit of more than one person watching the quality of the code.&lt;/li&gt; &lt;li&gt;we do continues integration in order to uncovers integration issues early.&lt;/li&gt; &lt;li&gt;we have short iteration cycles in order to verify that everything built until this point is fully functional according to the story cards and reviewed by the customers.&lt;/li&gt; &lt;li&gt;we put the customers (users) in the center of the project to ensure adequate client involvement and proper set of project priorities.&lt;/li&gt; &lt;li&gt;we communicate with the customers (users) constantly to ensure we evolve our understanding of the business domain, challenge assumptions, and make informed choices and decisions.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Should we even bother...&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;Since we apply very rigorously all practices listed above, we expect that very few defects of any type are introduced and the system is in relatively defect-free state at any given time.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Not so fast...&lt;/h4&gt;It turns out that most of the time we still end up with a lot of defects at the end of a project (mostly requirements defects) and still spend time and money doing the not so much exciting work of fixing bugs. Finally, we are only humans and we can make mistakes.&lt;br /&gt;&lt;p&gt;So, how do we deal with resolving defects in agile team in the most effective way?&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;In theory ...&lt;/h4&gt;Even the software engineering books very clearly state that "the earlier within the software life cycle a problem is discovered, the cheaper it is to fix". Also, fixing a defect in a much later stage of the project could be a prohibitingly expensive thing to do. This is definitely proven on many occasions to be true.&lt;br /&gt;&lt;p&gt;The strange thing is the fact that not too much has been written about that problem in agile literature. One of the most essential agile principles, however, is that an application delivered by the end of every iteration should be absolutely functional and ready to be used by the customers (even with very limited functionality). Iterative development is perhaps the single most important vehicle for managing requirements defects and in my opinion this should exclude the existence of any them.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;In practice ...?&lt;/h4&gt;But how many agile projects we know that end up having bug trucking systems with hundreds of bugs there waiting to be fixed. So, we finish the story cards for an iteration on time, we clap hands for one more good iteration where we deliver the most business value to the customer but we don’t bother too much dealing with bugs.&lt;br /&gt;&lt;p&gt;If we go back to the statement above that the defects are getting much more expensive to be fixed in latter iterations or phases of the project it could turn out that we probably didn’t deliver as much business value to the customer as we would’ve liked.&lt;br /&gt;&lt;/p&gt;Actually, most of the bugs are left for so called "bug fixing" or "application readiness" iteration(s) at the end of the project. This represents huge risk for a project, since we haven’t made any, even rough estimation for how much time it would take for these defects to be fixed. In reality, we would not be able to do any estimation since we don’t know how many more bugs will be discovered. More importantly, the time and the complexity for fixing current defects will increase in the time to the end of the project.&lt;br /&gt;&lt;h4&gt;Is this the right way...?&lt;/h4&gt;Of course, there is politics involved here too. Everybody wants to present nice graphs and charts in front of the customer but how is this better than using the waterfall way of thinking?&lt;br /&gt;&lt;h4&gt;So, what now...?&lt;/h4&gt;Since agile are not some well established processes (thankfully) but rather helpful guidelines, there is no one way to deal with this issue. Every agile team should find its own way to do things through constant retrospectives. Based on my experience while working in agile teams, there are two main assumptions that tend to lead to the &lt;i&gt;bug problem in an agile project&lt;/i&gt;:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;i&gt;The assumption that every software development project will indisputably need bug trucking system.&lt;/i&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;i&gt;The bugs are not prioritized together with the story cards in relation to the business value they represent.&lt;/i&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;Is this even open to debate...????&lt;/h4&gt;The first assumption is very similar to the assumption that we need a relational database in every project we are about to start. Probably, most of the time we do need some kind of database, but we should not just assume and implement some kind of infrastructure that is not driven by business needs (this is how we end up with so call "technical cards" that can not be justify with any business value for the customer but I am leaving this for other time).&lt;br /&gt;&lt;h4&gt;Did we overlook communication...?&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;Since every tool imposes some kind of process to be followed in some degree, an agile team should be particularly alert when picking tools to work with. Overall, an agile team should choose "people and communication over tools and processes". Sure enough, the bug trucking tools do a good job of keeping record of what kind of defects has been discover and much more information that we will ever need.&lt;br /&gt;&lt;p&gt;&lt;/p&gt;However, we should determine whether we loose the communication within the team by using such tools. What happens usually in practice is that a BA, QA or a user discovers a presumable defect in the system and enters it in a bug tracking database. Much later, probably at the end of the project, a developer opens the same bug to work on. By that time, all of the communication and most of the information about this bug is lost. The reasons could be many:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;the most important case is when we have requirements defects where a lot of functionality is built on top of wrong assumptions. This should not be so much severe in well designed OO systems but still it is going to be much, much more expensive than fixing a defect around the time when it was discovered.&lt;/li&gt; &lt;li&gt;most if not all of the bug trucking tools require owners assign to a defect. This is very close to code ownership and doesn’t stimulate the other team members to participate in the knowledge sharing while resolving a particular defect.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;it can’t be reproduced since many times the cases are very data specific.&lt;/li&gt; &lt;li&gt;many people that had worked on a particular functionality have left the project already.&lt;/li&gt; &lt;li&gt;developers and BAs have a clearer picture of what is going on with the system when a story card is implemented but they have hard time recall any issues latter on.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As a whole, later defect detection and repair is much more expensive, which is totally against one of the main aims of Agile development to lower the cost of a project.&lt;/p&gt;&lt;h4&gt;Defects and feature request are...&lt;/h4&gt;&lt;p&gt;&lt;a href="http://memeagora.blogspot.com/2006/02/d-cubed_02.html"&gt;Recent innovative software development methodology&lt;/a&gt; is &lt;a href="http://kirk.blog-city.com/bob_the_bug_db_filter_meets_mustang.htm"&gt;Defect Driven Design&lt;/a&gt; (D3, pronounced "D Cubed"). The idea is to remove the two major phases in a project development phase (as some call it - &lt;i&gt;defect creation&lt;/i&gt;) and maintenance phase (also called &lt;i&gt;defect removal&lt;/i&gt;) and have only one phase called probably &lt;i&gt;defect implementation&lt;/i&gt; phase. You can read more about this idea but the main point was that there is no distinction between a defect and a new feature request, story card, enhancement or whatever you want to call it.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;What provides more business value...?&lt;/h4&gt;&lt;p&gt;Even though D3 is still very open to debate, the idea that defects should not be separated from and prioritized differently than story cards is not easily ignored.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Usually customers don’t have problems prioritizing new functionality in regard to importance and business value for them. However, we would not see the same level of confidence when we ask customers, whether they prefer to have new functionality added or some previously prioritized and not currently working functionality fixed. Of course, the answer strongly depends on case by case basis but that’s why, we should not make assumption so that to eliminate defects from the prioritization process and treat them as something different than story cards.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Is there another way...?&lt;/h4&gt;It is not a big surprised the fact that there is not one efficient way to deal with defects in different agile teams. The same should be true for the assumption that bug tracking database is the best solution for every software project. We can have or try many possible scenarios:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;some kind of white board (either real or wiki based) where everybody can see current development of defects, the progress and all related communications.&lt;/li&gt; &lt;li&gt;customers and anybody else involved in acceptance testing can use some kind of recording test tools when they do manual testing. Firefox has very simple and user friendly plugging for Selenium test for example. With such a tool, a customer can very easily record any defect and then send the resulted failing test file. The file could be included immediately in the build and thus fixed as soon as possible. No time lost for reproducing errors or misunderstanding or some kind of blaming.&lt;/li&gt; &lt;li&gt;creating story cards for defects that are prioritized, estimated and accepted as any other story card is very appealing scenario. This will ensure that all defects are analyzed, discussed, prioritized and fixed in proper manner and time. There could be slight variations like creating story cards with letters or numbers in the name. Example, &lt;i&gt;Search For User&lt;/i&gt;, &lt;i&gt;Search for User- b&lt;/i&gt; or &lt;i&gt;Search for User When something happens&lt;/i&gt; and so on.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;How would we know it is better...?&lt;/h4&gt;Iterative development and team retrospectives after every iteration are perhaps the single most important vehicle for managing defects. Through retrospective and fast feedback we can determine how effectively we manage defects and whether we detect and fix them as early as possible. The goal is very clear and even more easily confirmable - we should not have &lt;i&gt;bugs fixing iterations&lt;/i&gt; at the end of an agile project.&lt;br /&gt;&lt;h4&gt;What actually I wanted to say...&lt;/h4&gt;The whole thing was to reassure myself and convince at least one more person that:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;many times we don’t need buck trucking databases since these kinds of tools almost always expose some process to be followed and the huge benefits of communication in an agile teams is lost.&lt;/li&gt; &lt;li&gt;defects are actually missing or not properly working features of the system and as such we should not make distinction between story cards and defects.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;br /&gt;&lt;/span&gt;A very good addition to this is "&lt;a href="http://dnicolet1.tripod.com/agile/index.blog?entry_id=1483836"&gt;... on features vs task post&lt;/a&gt;":&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="font-style: italic;"&gt;Instead of recognizing that defects must be prioritized and planned as stories, as Jon's post     suggests, defects are still considered "exceptions" as per traditional thinking about software development. There is a tendency to avoid treating them as real work items.&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113928747594141988?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2006/02/are-there-bugs-in-agile-project.html' title='Are there bugs in agile project?'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113928747594141988/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113928747594141988&amp;isPopup=true' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113928747594141988'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113928747594141988'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2006/02/are-there-bugs-in-agile-project.html' title='Are there bugs in agile project?'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113393768462707703</id><published>2005-12-07T00:29:00.000-06:00</published><updated>2005-12-07T18:57:49.763-06:00</updated><title type='text'>My Ruby Tipping Point</title><content type='html'>&lt;span style="font-weight: bold; font-style: italic;"&gt;(Updated)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was going to ramble about the best place to do business validations in a java application but I ran into this &lt;a href="http://jroller.com/page/thuss?entry=validation_belongs_in_the_domain"&gt;post&lt;/a&gt;. Todd says it very well. The only place where business logic belongs to such as business validation is in the domain objects. Not in the view, not in the controllers, not to even talk about putting them on facades, services, DTOs or some similar concepts that java community tends to like a lot.&lt;br /&gt;&lt;br /&gt;Ruby on Rails shows perfect example of good OOD with putting so elegantly all validations in the model. I struggle with similar concept in java but the situation there was different story. Most of the web frameworks provided some kind of validation in the view/controller part that were too tempting to be used. As a result, we have some of the validations in the view/controller, some in facades/services and sometimes in domain objects. The result is not very impressive. We have a lot of problems and possible defects if we have rich domain objects with a lot of collaboration among them since most of the business logic is placed outside of the domain.&lt;br /&gt;&lt;br /&gt;Throwing exceptions in the setters method or much more useful &lt;a href="http://www.martinfowler.com/eaaDev/Notification.html"&gt;Notification pattern&lt;/a&gt;  - domain object use notification object to collect information about errors during validation (implemented similarly in Ruby on Rails) are possible alternatives to have the validations in the model. So, the examples are out there and very convincing.&lt;br /&gt;&lt;br /&gt;Then I read the comments in the Todd’s blog and I realize that java community would never get it. Some of the comments are stating that the validations should be separated from the domain objects - preferably in xml file; others point out that putting validations in domain objects make validations not reusable and so on. Similar java thinking could been seen in &lt;span style="text-decoration: underline;"&gt;&lt;a href="http://forum.springframework.org/showthread.php?t=19429"&gt;this&lt;/a&gt; &lt;/span&gt;very long discussion in the Spring framework architectural forum about domain objects being bind to the view in a web application is very bad and we have to use DTO and facades.  All that was the tipping point for me.&lt;br /&gt;&lt;br /&gt;In my previous post “&lt;a href="http://igorstoyanov.blogspot.com/2005/11/learning-ruby-and-ruby-on-rails.html"&gt;Learning Ruby on Rails&lt;/a&gt;", I wrote that I like java because of the community. It looks like this is not the case any more. I really like the Ruby way of thinking and a very good example is the &lt;a href="http://martinfowler.com/bliki/HumaneInterface.html"&gt;Human Interfaces&lt;/a&gt;. We can achieve great things with Java as well but the community thinking is not going in this direction, even with frameworks such as Spring built around the principle of simplicity. My only hope is that Ruby would never become the same type of “enterprise” language as Java currently is.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Martin Flowers’s  &lt;a href="http://martinfowler.com/bliki/ContextualValidation.html"&gt;ContextualValidation&lt;/a&gt; is good addition to the &lt;span style="font-style: italic;"&gt;validation&lt;/span&gt; topic.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;“But one thing that I think constantly trips people up is when they think object validity on a context independent way such as an isValid method implies.”&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is much related to the first comment below:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;“…often some of my domain objects will be used across different projects and business rules vary based on the context.”&lt;/span&gt;&lt;br /&gt;As well as all other similar issues about validation in different user cases, when domain objects are used in batch processing with slightly different business rules and so on.&lt;br /&gt;&lt;br /&gt;Martin gives an excellent answer for that:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;“I think it's much more useful to think of validation as something that's bound to a context - typically an action that you want to do. Is this order valid to be filled, is this customer valid to check in to the hotel. So rather than have methods like isValid have methods like isValidForCheckIn.”&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113393768462707703?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/12/my-ruby-tipping-point.html' title='My Ruby Tipping Point'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113393768462707703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113393768462707703&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113393768462707703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113393768462707703'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/12/my-ruby-tipping-point.html' title='My Ruby Tipping Point'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113349793605755245</id><published>2005-12-01T21:53:00.000-06:00</published><updated>2005-12-02T09:01:13.200-06:00</updated><title type='text'>Dependency Injection OR  Service Locator in Domain Objects  with Spring and Hibernate frameworks</title><content type='html'>&lt;style type="text/css"&gt;&lt;br /&gt;    &lt;!--code { font-family: Courier New, Courier; font-size: 10pt; margin: 0px; }--&gt;&lt;br /&gt;&lt;/style&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;The Problem&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Currently, many java applications use Spring framework together with Hibernate. One of the advantages of that is that we can implement our domain and service objects as POJOs. Most of us are already convinced of all the benefits that such a type of architecture can have. In architecture like that, domain objects are managed by Hibernate and service objects are managed by Spring. Also, another advantage of using Spring specifically is Dependency Injections (DI) of services and resources.&lt;br /&gt;&lt;br /&gt;The problem is how to retrieve/find/locate services or resources in domain objects since they are managed by Hibernate and not created through the bean factory of Spring framework?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Note:&lt;/span&gt;  we should differentiate between domain, infrastructure and application services (Domain Driven Design book - &lt;a href="http://domaindrivendesign.org/book/"&gt;http://domaindrivendesign.org/book&lt;/a&gt;). Using infrastructure or application services in domain objects is rather not appropriate. The problem I am most concerned with here is in the case when we need to invoke domain services inside of  domain objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Can we avoid the problem?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Probably! The only way to avoid this problem is not to deal with any services/resources in domain objects. We can do this if we coordinate all domain-service cooperation from a service layer. In this case, we don’t need to bother with dependency injections, service locators, etc.  This makes a lot of sense when we invoke services in an asynchronous fashion and especially in SOA /EAI types of architectures.&lt;br /&gt;&lt;br /&gt;However, there are some disadvantages:&lt;br /&gt;-  We deprive ourselves from some of the benefits and power of OOP/OOD.&lt;br /&gt;-   Sometimes, service behavior fits very nicely into the domain model when we have a rich domain model rather than an anemic one &lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html"&gt;http://www.martinfowler.com/bliki/AnemicDomainModel.html&lt;/a&gt; and &lt;a href="http://wrschneider.blogspot.com/2005/01/avoiding-anemic-domain-models-with.html"&gt;http://wrschneider.blogspot.com/2005/01/avoiding-anemic-domain-models-with.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Why do we get to the problem?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When I start a project I always try to have very well separated service layer from domain objects (usually enforced with different compilation modules for domain objects and service layer). However, in practice (at least until now) it always turns out that at some point I will need to use some kind of service or resource in my domain objects (the simplest example is Time Service. A Time Service is usually needed to give synchronized time when the application is deployed / clustered to more than one server. Also, if you need to play with the current time in your tests, this is a perfect solution. Usually when you deal with some kind of payment/billing systems, you will definitely need something like the above). There can be numerous examples of domain objects using some kind of service. Usually, most of the applications that have more complex domains use some kind of services or resources in domain objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Common solution to the problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In the past when faced with this sort of situations we have usually used some form of Service Locator within domain objects in order to retrieve/locate services or resources.&lt;br /&gt;&lt;br /&gt;However, these days we routinely use Dependency Injection with some form of Inversion of Control lightweight container (Spring for example) to wire up practically everything else in an app - and we would like to use a consistent approach if at all possible. Unfortunately, our domain objects are constructed by Hibernate and not Spring.&lt;br /&gt;&lt;br /&gt;The most common solution (and the only one that I have seen in practice for now) is to use Spring framework DI to inject services into the service layer and to wire up practically everything else in your app beside domain objects. The domain objects, on the other side use Spring-based service locators to find further services/collaborators they need to do their job.&lt;br /&gt;&lt;br /&gt;This could be workable approach since both the DI and service location mechanisms use the same underlying infrastructure (Spring bean factory), so they can share the same configuration files etc. Also, this common solution to the problem has been kind of described in the javadocs for Spring’s BeanFactoryBootstrap class with the statement “one singleton to rule them all”. In other words, allow singleton access to the bean factory or application context that holds all of the service layer objects.&lt;br /&gt;&lt;br /&gt;However, as I stated above, I would like to use a consistent approach if at all possible for retrieving services. Not to mention all problems that comes with using Service Locator pattern. I guess using Service Locator with DI injections is a little better than the old style Service Locator but at the end, this is still a singleton. At least there is only ONE singleton in the entire app instead of one for each service object.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Example implementation of the common solution with Service Locator and DI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Before I continue further, let me show brief example of Service Locator using Spring DI. ServiceManager is an implementation of Service Locator pattern in this example. Its conceptual implementation comes from the statements “one singleton to rule them all” and “another level of indirection can solve any problem in OO design” (I don’t fully agree with this statements but it is hard to argue against them). The ServiceManager class has reference to all services that are needed by domain objects. All services are injected by Spring and ServiceManager is singleton instantiated by Spring creation factory on application startup. Something like this:&lt;br /&gt;&lt;div class="java" align="left"&gt;&lt;table bg="" style="color: rgb(255, 255, 255); width: 668px; height: 380px;" border="0" cellpadding="3" cellspacing="0"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;&lt;td align="left" nowrap="nowrap" valign="top"&gt;&lt;code&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public class &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ServiceManager &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;private static &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;ServiceManager ourInstance;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;IReferenceDataService referenceDataService;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;private &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ITimeService timeService;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;…………&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;//other service declarations&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ServiceManager&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;              &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;ourInstance = &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85); font-weight: bold;"&gt;this&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0); font-weight: bold;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public static &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;IReferenceDataService getReferenceDataService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;              &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;return &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;getInstance&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.referenceDataService;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;//setter for Spring injection&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;setReferenceDataService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;IReferenceDataService referenceDataService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;             &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;this&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.referenceDataService = referenceDataService;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;……&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;//other service setters/getters&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;protected static final &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ServiceManager getInstance&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;             &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;return &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ourInstance;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;!-- end source code --&gt;&lt;br /&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;td style="vertical-align: top;"&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;and the Spring mapping:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);font-size:95;" &gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="serviceManager"  class="service.impl.ServiceManager"&amp;gt;&lt;br /&gt;       &amp;lt;property name="referenceDataService"&amp;gt;&lt;br /&gt;           &amp;lt;ref local="referenceDataService"/&amp;gt;&lt;br /&gt;       &amp;lt;/property&amp;gt;&lt;br /&gt;       &amp;lt;property name="timeService"&amp;gt;&lt;br /&gt;           &amp;lt;ref local="timeService"/&amp;gt;&lt;br /&gt;       &amp;lt;/property&amp;gt;&lt;br /&gt;       &amp;lt;property name="securityService"&amp;gt;&lt;br /&gt;           &amp;lt;ref local="securityService"/&amp;gt;&lt;br /&gt;       &amp;lt;/property&amp;gt;&lt;br /&gt;       .......&lt;br /&gt;       &amp;lt;!-- other service declarations --&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Many people do consider that this is perfectly fine solution and there are not any problems with it. If you are some of these people, probably the rest would not be of such an interest for you.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;Issues with using Service Locator with DI&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have encountered several problems with such an implementation:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. We end up with more than one way to retrieve a service, mock or stub. &lt;/span&gt;&lt;br /&gt;In some not domain objects, we get a service through Spring injections, in others we get it through static call to ServiceManager class. I feel this approach could bring a little confusion. This inconsistent approach of retrieving services could be a problem but I guess it could be argued that this is more of a question of “Enabling Attitude”: &lt;a href="http://martinfowler.com/bliki/EnablingAttitude.html"&gt;http://martinfowler.com/bliki/EnablingAttitude.html&lt;/a&gt; rather than a problem with using Service Locator together with DI. However, I found out that this could be an actual problem in many practical situations. At the end, remembering when to use what is still an indicator for a “code smell”.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Another major problem is that ServiceManager is very hard to be tested, mocked or stubbed.&lt;/span&gt;&lt;br /&gt;The example implementation could enable us to mock specific services provided by the ServiceLocator through sub classing the ServiceLocator class and providing methods for overriding of a particular service.&lt;br /&gt;&lt;div class="java" align="left"&gt;&lt;table bg="" style="color: rgb(255, 255, 255);" border="0" cellpadding="3" cellspacing="0"&gt;&lt;br /&gt;&lt;tbody&gt;&lt;tr&gt;  &lt;!-- start source code --&gt;&lt;br /&gt;&lt;td align="left" nowrap="nowrap" valign="top"&gt;&lt;code&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public class &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ServiceManagerStub &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;extends &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ServiceManager &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public static &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;overrideTimeService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ITimeService timeService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;getInstance&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.setTimeService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;timeService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public static &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;overrideSecurityService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;ISecurityService securityService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;            &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;getInstance&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.setSecurityService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;securityService&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.................&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;//other service overridings&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;!-- end source code --&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Before we congratulate ourselves with successfully solving infrastructural issues that already has been solved by a DI lightweight container, which by the way we already use, I will try to point out some new problems that are introduced with this solutions.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;The problem comes from the fact that we still use static class methods to retrieve services. So when we set up a mock service in a single test (ServiceManagerStub.overrideTimeService(getMockedTimeService()), we have to remember to reset it in the tearDown method. Again “we should remember”. Of course many times this is not done since running a single test class in an IDE would not cause a problem. Then we run all test from the build. At some point, we have a situation when  a test which passes in an IDE fails in the build. The reason is that this test could be about 10-20 test classes after the one where we set up the mocked service. Some of the objects in this particular test use ServiceManager class to retrieve the same service that we mocked previously and we forget to reset it. Of course, we don’t have even a clue that a mocked service is invoked instead of a real one and we can not even think that 10-20 tests before our test, someone else have set a mocked implementation of the service we need.&lt;br /&gt;Anyway, to make the story short, if somebody has used this kind of ServiceLocator, he/she should be familiar with this type of problems.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. Issues with dynamic class loading.&lt;/span&gt;&lt;br /&gt;Any implementation of ServiceLocator that uses calls to static class methods will have problem with releasing the static reference from the memory potentially with every dynamic class loading in a J2EE application server on hot redeploying. I have definitely had a lot of class loader issues with WebSphere 5. (Not with Jetty BTW)&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. One of the consequence of using ServiceLocator is that we hard-wire it.&lt;/span&gt;&lt;br /&gt;This makes reusing of the domain objects that have hard coded dependence on the ServiceLocator often impossible due to dependencies on the particular application’s initialization and service infrastructure. In some of the cases, we were trying to reuse our domain objects in another application that will deal mostly with integration and will not use our current service infrastructure.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. Another more general problems&lt;/span&gt;&lt;br /&gt;- ServiceLocator cut against interfaces, by forcing you to know about specific class.&lt;br /&gt;-  Using ServiceLocator in the beginning could not be a big problem. However, it could turn out that ServiceLocator class is access simultaneously by many threats and it is a performance bottleneck. In cases like that we can't switch to using a pool of such objects for any of the callers that have hard-coded dependency on ServiceLocator class. Velocity and Struts frameworks, for example, have found that this initial assumption can end up being wrong and restrictive.&lt;br /&gt;&lt;br /&gt;I guess that we can find a solution to all problems related to ServiceLocator and most of them depend on how it is implemented but should we have to deal with all these problems on the first place when we already have an implemented solution in form of DI.&lt;br /&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;&lt;br /&gt;Alternative Solutions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;1. Passing a service as a parameter in the method call.&lt;/span&gt;&lt;br /&gt;Passing a service as a parameter would remove the problem of dealing with dependency injection, service locators, etc and could be an elegant solution in some cases. However, in most of the situations, especially when we have rich domain object model this would not be a workable solution.&lt;br /&gt;&lt;br /&gt;I suspect that following this approach for a more complicated domain would result in behavior moving itself inexorably out of the domain and into our service layer - leaving us with the ubiquitous anemic domain model. Usually, my goal is for the service layer to be very thin - in the majority of cases each service would just find the domain object(s) it needs and then call a method on the domain - all the behavior would be part of the domain.&lt;br /&gt;&lt;br /&gt;Also, when the object behavior is not controlled by ‘Transactional Script” ( &lt;a href="http://martinfowler.com/eaaCatalog/transactionScript.html"&gt;http://martinfowler.com/eaaCatalog/transactionScript.html &lt;/a&gt;) but rather than the flow of control emerges from object behavior in rich domain model, we usually have situation when one object delegate to another object, which call a third object and so on. In situations like that, we would need to simply propagate the service in every method in the chain if this service happens to be needed in the last one, for example. Something like this anti-pattern description:  &lt;a href="http://www.picocontainer.org/Propagating+Dependency"&gt;http://www.picocontainer.org/Propagating+Dependency&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;2. Using Hibernate to set the services/resources&lt;/span&gt;&lt;br /&gt;This is probably the most compelling solutions since Hibernate anyway mange our domain objects. There are a couple of ways to do this. A god solution using Spring Sandbox classes is described here:&lt;br /&gt;&lt;a href="http://jroller.com/language/taranis/20050204?language=nl"&gt;http://jroller.com/language/taranis/20050204?language=nl&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another solution is to use the currently available hibernate interceptors:&lt;br /&gt;&lt;a href="http://forum.springframework.org/archive/index.php/t-10547.html"&gt;http://forum.springframework.org/archive/index.php/t-10547.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Example of using AuditInterceptor to inject TimeService in domain objects can look like that:&lt;br /&gt;&lt;span style="color: rgb(51, 102, 255);font-size:95;" &gt;&lt;br /&gt;&amp;lt;bean id="time-service" class="service.TimeService"/&amp;gt;&lt;br /&gt;&amp;lt;bean id="audit-interceptor" class="persistence.AuditInterceptor"&amp;gt;&lt;br /&gt; &amp;lt;property name="timeService"&amp;gt;&lt;br /&gt;     &amp;lt;ref bean="time-service"/&amp;gt;&lt;br /&gt; &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id="hibernate-session-factory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"&amp;gt;&lt;br /&gt; &amp;lt;property name="dataSource"&amp;gt;&lt;br /&gt;     &amp;lt;ref bean="jdbc-data-source"/&amp;gt;&lt;br /&gt; &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;property name="entityInterceptor"&amp;gt;&lt;br /&gt;     &amp;lt;ref local=" audit-interceptor"/&amp;gt;&lt;br /&gt; &amp;lt;/property&amp;gt;&lt;br /&gt; &amp;lt;property name="mappingResources"&amp;gt;&lt;br /&gt;     &amp;lt;list&amp;gt;&lt;br /&gt;       &amp;lt;value&amp;gt;&lt;br /&gt;             /somepackage/SomeDomainObject.hbm.xml&lt;br /&gt;         &amp;lt;/value&amp;gt;&lt;br /&gt;     ... ... ... ... ...&lt;br /&gt;     &amp;lt;/list&amp;gt;&lt;br /&gt; &amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;The problem with using hibernate interceptors is that they will be fired up only when the domain object is either saved or retrieved from the database. Of course by the point you need to save a domain objects, you don’t need the service any more. So, if you need to inject services or resources in objects that are only retrieved from a database (never create new objects and then persist them) this approach will be very elegant solution.&lt;br /&gt;&lt;br /&gt;However, when we create a new domain object, this interceptor is not going to be fired and we won’t have the resources or services injected in the newly created object.&lt;br /&gt;Needles to say, that this is the most common scenario in practice. We will definitely have many places where we need to create a new object, perform some business operation on it and then persist it to a database. In situation like that we need to have/inject/retrieve any services/resources before we push it to Hibernate through session.save()  for example. As some of the people from Spring framework suggest (&lt;a href="http://opensource2.atlassian.com/projects/spring/browse/SPR-431"&gt;http://opensource2.atlassian.com/projects/spring/browse/SPR-431&lt;/a&gt;) we can use Spring via the ApplicationContext to create the domain object instance, populate it into our system via a lookup-method (to keep coupling low), and then push it into Hibernate.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;3. Using Srping Bean factory to create your domain objects&lt;/span&gt;&lt;br /&gt;In order to inject a service during creation of a domain object, we can use the Spring factories BeanNameAutoProxyCreator and ProxyFactoryBean:&lt;br /&gt;&lt;a href="http://www.springframework.org/docs/reference/aop.html#aop-pfb"&gt;http://www.springframework.org/docs/reference/aop.html#aop-pfb&lt;/a&gt;&lt;br /&gt;And some opinion about the difference between ProxyFactoryBean and &lt;a href="http://www.blogger.com/BeanNameAutoProxyCreator%20http://erik.jteam.nl/?p=8"&gt;BeanNameAutoProxyCreator http://erik.jteam.nl/?p=8 &lt;/a&gt;&lt;br /&gt;As the name suggests (although they use AOP) they are still factories. This means that you can’t create an object just with “new”, but you have to use some kind of factory (in this case Spring bean factory). The other problem is that in order to use these Spring bean factories or Spring AOP for that matter, the lifecycle of a domain objects should be managed by the Spring container. If this is not a concern for you, then these bean factories together with Spring AOP will do the job.&lt;br /&gt;&lt;br /&gt;So, if we don’t have problem with Spring container managing the life cycle of our domain objects, we have the ability to intercept the creation of a domain object despite the fact that the creation of this object is managed by Hibernate as well.&lt;br /&gt;&lt;br /&gt;One problem with this approach is that we have to create all of our domain objects via&lt;br /&gt;factory and our domain objects will become dependent on Spring framework. Since I usually try to keep all business logic in pure POJO, having domain objects dependent on Spring is somewhat problematic. Another problem will be unit testing our domain objects. We should initialize Spring application context before running any test. This can slow a great deal our unit tests and we can loose one of the biggest benefits of unit testing – very fast feedbacks. Not to mention that the task of refactoring the creation of all domain object from using “new” to using factory is almost impossible to be done in respects of agile iterative approach.&lt;br /&gt;&lt;br /&gt;Also, many people don’t think that this is very efficient solution either. Some of the arguments are about performance issues of Spring AOP implementation: &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=30681"&gt;http://www.theserverside.com/news/thread.tss?thread_id=30681&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;So, if the biggest problem in this approach is the dependency on Spring bean factory, then we can work around it through using directly AOP in order to inject services in our domain objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;4. Using AOP (AspectJ) to inject services/resources in domain objects during their instantiation. &lt;/span&gt;&lt;br /&gt;Finding resources or services (Dependency Location/ Look Up) should not be a concern of a domain object to deal with. One of the basic principles of OOP is that one object should have only one responsibility and should do it well. Looking up for resources or services is clearly a cross-cutting problem. This should be a very good candidate for AOP. We can use AspectJ in order to inject services/resources in DO both when they are loaded and when new ones are constructed.&lt;br /&gt;&lt;br /&gt;One issue with this approach is that the use of Spring DI for everything else and AspectJ for DO is not a consistent approach. Still, in my opinion it is better that a static call in DO to class method in Service Locator object. Also, you can integrate very easily AspectJ with Spring:&lt;br /&gt;&lt;a href="http://static.springframework.org/spring/docs/1.2.x/reference/aspectj.html#d0e4554"&gt;http://static.springframework.org/spring/docs/1.2.x/reference/aspectj.html#d0e4554&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It looks like finally we have some feasible solution to the problem. Not so fast! According to my experience in dealing with customer enterprise applications and also according to many other opinions on AOP (one of them:&lt;a href="http://beust.com/weblog/archives/000180.html"&gt; http://beust.com/weblog/archives/000180.html&lt;/a&gt;) most of developer community (as well as IT as a whole) remains very skeptical about a direct adoption of AOP. The idea of using open source aspect oriented compiler could be very problematic on many enterprise projects.&lt;br /&gt;&lt;br /&gt;As a whole, I think that this is the least popular solution and the hardest one to sell it out to other developers, architects and especially to customers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;5. Using Hibernate to set the services/resources when retrieving DO and setting them directly when a new DO is instantiated.  &lt;/span&gt;&lt;br /&gt;We can inject services/locators as with Hibernate interceptors when we retrieve objects from a database. When we create a new object, we can have the needed services/resources as a constructor parameter or just to set a property to the newly created DO.&lt;br /&gt;&lt;br /&gt;Again we have at least two places that will deal with injecting services/resources – Hibernate interceptors as well as every place in the code where we create a new DO, which needs services. This probably will make us use a factory for creating DO, which brings us back to the solution with Spring bean factory managing our domain objects. Very informative discussion about this approach could be found here:&lt;br /&gt;&lt;a href="http://forum.springframework.org/showthread.php?t=12221"&gt;http://forum.springframework.org/showthread.php?t=12221&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the first time I feel that there is some inconsistency of using Spring framework for DI.  To me, all this seems to beg the question - If Spring framework doesn’t provide effective way for DI in the domain model - and we want the majority of behavior to be in our domain model – then how we have to deal with this problem?&lt;br /&gt;&lt;br /&gt;Anyway I still think that Spring framework is a great framework. In my opinion using AOP directly with AspectJ is the best approach for DI in the domain model. However, since AOP is not even close to wide spread adoption, probably the alternative solution to AOP in java5 – annotations could have the potential to solve the problem in less powerful but still elegant way (&lt;a href="http://weblogs.java.net/blog/crazybob/archive/2004/09/where_is_aop.html"&gt;http://weblogs.java.net/blog/crazybob/archive/2004/09/where_is_aop.html&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;What approach are you using in your projects?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113349793605755245?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/12/dependency-injection-or-service.html' title='Dependency Injection OR  Service Locator in Domain Objects &lt;br&gt; with Spring and Hibernate frameworks'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113349793605755245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113349793605755245&amp;isPopup=true' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113349793605755245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113349793605755245'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/12/dependency-injection-or-service.html' title='Dependency Injection OR  Service Locator in Domain Objects &lt;br&gt; with Spring and Hibernate frameworks'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113228972259263476</id><published>2005-11-17T22:38:00.000-06:00</published><updated>2005-11-18T03:25:18.726-06:00</updated><title type='text'>Interactive Tests – Mocks to the Extreme!</title><content type='html'>&lt;p&gt;If you do Behavior Driven Development (BDD) or in less extend applicable if you do Test Driven Development (TDD), you will definitely get to a situation where you need to know that a certain method has been call but you are not interested in what is going on inside of this method. You don’t want to check whether the state of an object has been changed. It is responsibility to another unit test – “Try to use only one assert per test” – (Behavior Driven Development)&lt;/p&gt;    &lt;p&gt;So, Nothing new here. I can use a mock object and specify the expected behavior I need. However, the complication comes when the method that I want to mock is specified in the same class I am testing. Example of this would be some service object that has method to retrieve data from a database and another method in the same class that filters this collection. How do we mock the database access method in order to verify the behavior of the filter method?&lt;/p&gt;&lt;!-- ======================================================== --&gt;&lt;!-- = Java Sourcecode to HTML automatically converted code = --&gt;&lt;!-- =   Java2Html Converter V4.1 2004 by Markus Gebhard  markus@jave.de   = --&gt;&lt;!-- =     Further information: http://www.java2html.de     = --&gt;&lt;div class="java" align="left"&gt;&lt;table style="width: 425px; color: rgb(255, 255, 255);" bg="" border="0" cellpadding="3" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr&gt;&lt;!-- start source code --&gt;&lt;br /&gt;&lt;td align="left" nowrap="nowrap" valign="top"&gt;&lt;code&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;public class &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;SomeClass &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Collection retrieveSomeData&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(){ &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// goes to db.}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Collection filterBySomeCriteria&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(){&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;                 &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Collection all = retrieveSomeData&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;                 &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// apply some rules to filter&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;                 &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;return &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;filteredCollection;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;           &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;If it      is not easy to verify the behavioral specification of a specific context,      then it should be refactor via Template, Strategy or some other form of      collaboration. This is definitely very good principle that I follow a lot.      One of the primary reasons for me to use BDD/TDD is to be able to design easily      testable and verifiable behavior as well as a simple overall abstraction      of a problem.  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;ol style="margin-top: 0in;" start="2" type="1"&gt;&lt;li class="MsoNormal" style=""&gt;Another      solution is to create something like a proxy object, which overrides the      method with some stub implementation. This is definitely possible and it is      a technique that I used to do a lot in the past when testing methods that      use Singletons objects. (Service Locator Patter - thankfully not any more      with DI). However, it is as unnatural as to try to set specific data to db      and then retrieved before verifying.&lt;/li&gt;&lt;/ol&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;ol style="margin-top: 0in;" start="3" type="1"&gt;&lt;li class="MsoNormal" style=""&gt;Sometimes      however, you probably don’t want to refactor similar implementation to      another collaborating object (because of “Cohesion”, “Completeness”,      “Convenience”, “Consistency” or some other reason). In situation like      that, we can very easily create a proxy of the object under test and      stub/mock the method that we want. We can create such an object by      ourselves, similar to 2). However, much more convenient is to use some      framework like &lt;a href="http://www.easymock.org/"&gt;EasyMock&lt;/a&gt;. &lt;/li&gt;&lt;/ol&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;In EasyMock, we can mock not only against interfaces (much preferable) but against actual classes and even the class under test. The example above would be:&lt;/p&gt; &lt;div class="java" align="left"&gt;&lt;table bg="" style="color: rgb(255, 255, 255);" border="0" cellpadding="3" cellspacing="0"&gt;   &lt;tbody&gt;&lt;tr&gt;&lt;br /&gt;&lt;br /&gt;&lt;!-- start source code --&gt;&lt;br /&gt;&lt;td align="left" nowrap="nowrap" valign="top"&gt;&lt;code&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;    public &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;void &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;testShouldFilterBySomeCriteriaWhenThereAreMoreThanOneElements&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;() {&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// create mock control for this class&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;MockControl someClassControl = createClassControl&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;SomeClass.class, &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;new &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Method&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;br /&gt;           SomeClass.&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;class&lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.getMethod&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(42, 0, 255);"&gt;"retrieveSomeData"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;new &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Class&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] {}) })&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// create the actual class under test.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;        SomeClass someClass = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;SomeClass&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;someClassControl.getMock&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// expected returned result for the mocked method.&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Collection retrievedData = Arrays.asList&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(127, 0, 85);"&gt;&lt;b&gt;new &lt;/b&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;Object&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;[] { &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;object1, object2 &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;})&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// set the expectations&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;someClassControl.expectAndReturn&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;someClass.retriveSomeData&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, retrievedData&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;   &lt;br /&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;classControl.reply&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;assertEquals&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(42, 0, 255);"&gt;"One entry should be filtered"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(153, 0, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;, someClass.filterBySomeCriteria&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;.iterator.size&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;())&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// since we need this more as a stub rather than a mock,&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// it is not advisable to verify the expected behavior&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(63, 127, 95);"&gt;// anyway, if you really need to&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;        &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;classControl.verify&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;()&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 255, 255);"&gt;    &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;}&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/td&gt;&lt;br /&gt;&lt;!-- end source code --&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;As everything else, we should be careful not to abuse this kind of testing.   &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113228972259263476?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/11/interactive-tests-mocks-to-extreme.html' title='Interactive Tests – Mocks to the Extreme!'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113228972259263476/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113228972259263476&amp;isPopup=true' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113228972259263476'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113228972259263476'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/11/interactive-tests-mocks-to-extreme.html' title='Interactive Tests – Mocks to the Extreme!'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6178209.post-113202924936202537</id><published>2005-11-14T22:27:00.000-06:00</published><updated>2005-11-14T22:34:47.456-06:00</updated><title type='text'>Learning Ruby and Ruby on Rails</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Why:&lt;/span&gt;&lt;br /&gt;After all the talk about Ruby/Rails. Also, so many highly respectful people in Java community raved so much about Ruby/Rails. Probably, there is something.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Background:&lt;/span&gt;&lt;br /&gt;I am Java guy. I have one-two year experience with .NET as well but I don’t want to go back there (at least not voluntarily). Why? I like a little more methodical oriented Java community (many could read this as unnecessary complex but still). Also, it turned out that I am not so much Java developer rather I am Eclipse/IntelliJ developer. However, I like the simplicity in design, so I thought I could learn many valuable things from Ruby/Rails and probably become very passionate about them.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;When:&lt;/span&gt;&lt;br /&gt;When I found out a comparably decent (for dynamic language) plugging for Eclipse – (the same debugging as in Java, some auto-completions as well) and when I find recommendation for good books – “Programming Ruby” and “Agile Web Development with Rails”. Why so late? I have 1-2 years with Python and Plone. I didn’t think that there could be something so much new or interesting.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Progress – Learning by comparison:&lt;/span&gt;&lt;br /&gt;I am learning Ruby/Rails with by reading various sources like blogs, books, articles, example applications and various tutorials. I can’t help but compare with all of my previous experience in web development. However, my experience with Ruby/Rails continues to be somehow mixed. Ruby so far is very comparable to Python (fortunately without the indentation stuff). I am still not so much after dynamic languages but I kind of like many features in Ruby and so far, Ruby is more than I expected.&lt;br /&gt;&lt;br /&gt;Rails framework, on the other hand was a little disappointing for me (at least for now).&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Left aside all of the limitation of Active Record mapping compared to Data Mapper/Identity   Map/Unit of Work patterns implemented by Hibernate (http://www.theserverside.com/articles/article.tss?l=RailsHibernate), I still don’t understand why our domain objects should inherit from Active Record base class. So many problems because of framework inheritance (also seen in Entity Beans!). What's more, how we unit test our domain objects without going to a database?&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The whole approach of defining the model in a database first as well as thinking of database state instead of object behavior looks to me like we are going way back.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;After having successful implementation with pure html template (Tapestry), it is not clear to me why we are going back to early days of php, jsp and asp with spaghetti mix of ruby code within html tags.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Also, after working two years with component based web framework like Tapestry, JSF and even ASP.Net, it is very hard for  me to accept that I have to iterate through  elements every time when I just want to have a simple table, for example.&lt;/li&gt;&lt;/ul&gt;On the positive side, I never saw something even close in Java to the controller/listeners implementation in Rails. I was really impressed by this simplicity.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next&lt;/span&gt;&lt;br /&gt;Overall, I am still excited to continue learning Ruby and Ruby on Rails. I see some benefits in creating not to complex websites, creating fast prototypes, huge potential in testing and even in the integration where we need more “relax” and definitely more simple way of doing things. Besides, if Ruby turns out to be big and there are exciting projects to work on, I don’t want to miss them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113202924936202537?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/11/learning-ruby-and-ruby-on-rails.html' title='Learning Ruby and Ruby on Rails'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113202924936202537/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113202924936202537&amp;isPopup=true' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113202924936202537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113202924936202537'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/11/learning-ruby-and-ruby-on-rails.html' title='Learning Ruby and Ruby on Rails'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113073784786640246</id><published>2005-10-30T23:50:00.000-06:00</published><updated>2005-10-31T00:33:31.170-06:00</updated><title type='text'>Stubs or Mocks - State or Behavior - Testing or Design: Evaluated!</title><content type='html'>Many discussions about my previous blog entry &lt;a href="http://igorstoyanov.blogspot.com/2005/10/stubs-or-mocks-state-or-behavior.html"&gt;Stubs or Mocks - State or Behavior - Testing or Design&lt;/a&gt;, made me write some summary and also share my experience on that controversial but kind of important topic.&lt;br/&gt;&lt;br/&gt; The main arguments for using state base rather than using more interactive based unit tests are:&lt;br/&gt;&lt;br/&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Most of the times the unit tests don’t catch all problems. &lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Some extracts:&lt;br/&gt;&lt;ul&gt;&lt;li&gt;“...&lt;em&gt;things often go wrong where one part of a system communicates with another (e.g. business logic connects to a database). The mocked out functions are usually called correctly, but something else is going wrong (e.g. permissions have not been set on the database)&lt;/em&gt;.” (from comments)&lt;/li&gt;&lt;br/&gt;&lt;li&gt;&lt;em&gt;“Why we should use mocks when we could test for free all underlying layers?” &lt;/em&gt;(other developers conversations).&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;em&gt;“In essence state-based tests are not just unit tests, but also mini-integration tests. As a result many people like the fact that client tests may catch errors that the main tests for an object may have missed, particularly probing areas where classes interact. Interaction tests lose that quality. In addition you also run the risk that expectations on interaction-based tests can be contradictory, resulting in unit tests that run green but mask inherent errors.”&lt;/em&gt;(Fowler).&lt;/ll&gt;&lt;/ul&gt;&lt;br/&gt;&lt;br/&gt;2) &lt;strong&gt;Coupling test to implementation.&lt;/strong&gt;&lt;br/&gt;3) &lt;strong&gt;Coupling to the implementation also interferes with refactoring, since implementation changes are much more likely to break tests than with state-based testing.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;The first argument is very debatable since there are so many different opinions on the definition of what is unit test. I completely agree with the definition of “&lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;unit test&lt;/a&gt;” from Wikipedia:&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;&lt;em&gt;“Limitations&lt;/em&gt;&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;Unit-testing will not catch every error in the program. By definition, it only tests the functionality of the units themselves. Therefore, it will not catch integration errors, &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Performance_testing"&gt;performance&lt;/a&gt;&lt;em&gt; problems and any other system-wide issues. In addition, it may not be easy to anticipate all special cases of input the program unit under study may receive in reality. Unit testing is only effective if it is used in conjunction with other &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Software_testing"&gt;software testing activities&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;br/&gt;&lt;em&gt;It is unrealistic to test all possible input combinations for any non-trivial piece of software. A unit test can only show the presence of errors; it cannot show the absence of errors.&lt;/em&gt;&lt;br/&gt;&lt;strong&gt;&lt;em&gt;Separation of Interface from Implementation&lt;/em&gt;&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;Because some classes may have &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Reference_%28computer_science%29"&gt;references&lt;/a&gt;&lt;em&gt; to other classes, testing a class can frequently spill over into testing another class. A common example of this is classes that depend on a &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Database"&gt;database&lt;/a&gt;&lt;em&gt;: in order to test the class, the tester finds herself writing code that interacts with the database. This is a mistake, because a unit test should never go outside of its own class boundary. As a result, the software developer abstracts an interface around the database connection, and then implements that interface with their own &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;mock object&lt;/a&gt;&lt;em&gt;. This results in &lt;/em&gt;&lt;a href="http://en.wikipedia.org/wiki/Loosely_coupled"&gt;loosely coupled&lt;/a&gt;&lt;em&gt; code, minimizing dependencies in the system.&lt;/em&gt;” (Wikipedia)&lt;br/&gt;&lt;br/&gt;For the rest of the arguments I will try to show the evolution of the style of unit testing in my current project and all problems related to that.&lt;br/&gt;&lt;br/&gt;&lt;em&gt;(All resemblance to real people or code is absolutely on purpose!)&lt;/em&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Phase 1: Mostly state based testing – not using mocks or stubs.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;We didn’t think to much about our tests in the beginning. The tests were mainly state based without any consideration for behavior driven design, mocking or stubbing some parts of the system or for the time of our build.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Consequences:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Since we didn’t mock or stub the database access, our test became a little slow for the current code base. &lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br/&gt;The rational of not using stubs or mocks was that by using Hibernate, we can use level 1/level 2 Hibernate caches, which would mean that we would not go to the db very often. Even if we query the db directly, we shouldn’t worry about speed with today’s state of computers and databases.&lt;br/&gt;&lt;br/&gt; So, a little slowness in our tests did make us think about some kind of mocking or subbing but since we didn’t have any other problems, we didn’t change anything.&lt;br/&gt;&lt;br/&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Our tests were strongly dependent on the test data in the database.&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;br/&gt;Since, we were doing mostly state base testing without using any mocks or stubs, our tests strongly relied on test data in the db. The same was true for the unit test in layers not immediately related to the database. Tests from many different layers started failing when something is wrong with the db or there were slight modifications in the test data. I guess that test in isolation principle didn’t stand any more, and we had hard time discovering where was the underling problem? &lt;br/&gt;&lt;br/&gt;An example would be when we retrieve some reference data and verify the size of the retrieved collection. Once we check this size in DAO layer, then we check the same in the service layer since the service layer call dao object. Finally, we check for the same size in the view controller class where we construct the drop down component for the UI. You can imagine how many test will fail if we add one more reference data entry in the underling database. This was just because we tried to do state based testing instead of more interactive one.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Actions taken:&lt;/strong&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Since we started having so many problems after simple changes to the test data in the db and tests became a little slow, we decided to use stubs or/and mocks but only for the database access layer. So, we had persistence tests that tested the database access and our DAO. We used mocks to verify whether a service has called a dao. Also, we used stubs when we didn’t care if the object has been persisted or not. When I say stubs, this is a little conditional. Sometimes, we used static stubs, but most of the time we used mocks as stubs - without verifying the behavior after using it. &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Phase 2: Mostly state based testing – with using mocks or stubs only for database access in the layers above it. &lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp; Consequences:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1. OO design became a “little” too corrupted. &lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1.1&amp;nbsp;&amp;nbsp;The state of the objects was exposed just to be tested without any other need in the application.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;We had the following code in our application:&lt;br/&gt;&lt;br/&gt;public class Name {&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;//public for testability &lt;/strong&gt;&lt;br/&gt;public Name(){&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;public Name(String firstName, String lastName){&lt;br/&gt;}&lt;br/&gt;…………&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;//public for testability &lt;/strong&gt;&lt;br/&gt;public void setLastName(String lastName){&lt;br/&gt;………………..&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;//public for testability &lt;/strong&gt;&lt;br/&gt;public Long getId(){&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;Of course, this was the immediate consequence of the &lt;strong&gt;state base testing. &lt;/strong&gt;When we created the test first, we didn’t think what BEHAVIOR we need, rather we thought of how to verify that the state of the object was set correctly&lt;em&gt;. (We should think very carefully whether we are doing OOP, if we need to create/expose some getter/setter or any kind of internal state for that matter just to test if something went well)&lt;/em&gt;&lt;br/&gt;It turns out, that this is common pattern on many other projects, so not many people were concerned about it.&lt;br/&gt;(&lt;em&gt;And yes, Hibernate can work not only with public but also with private/protected constructors, getters and setters&lt;/em&gt;)&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br/&gt;&lt;strong&gt;1.2. Instead of building rich &lt;/strong&gt;&lt;a href="http://www.martinfowler.com/eaaCatalog/domainModel.html"&gt;Domain Model&lt;/a&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;with objects that collaborate among each other, we end up having &lt;/strong&gt;&lt;a href="http://www.martinfowler.com/bliki/AnemicDomainModel.html"&gt;Anemic Domain Model&lt;/a&gt; .&lt;br/&gt;&lt;br/&gt;Since testing was very coupled with the state implementation of the tested classes, we started &lt;em&gt;“treating objects like new age data structures: Ask an object for information about its state, process that, make decisions based on that, then do something to/with the object. This is a classic approach from the old days or procedural programming. It is NOT OO.” &lt;/em&gt;(Astel)&lt;br/&gt;&lt;br/&gt;&lt;em&gt;“By pulling all the behavior out into services, controllers and so on, essentially end up with &lt;/em&gt;&lt;a href="http://martinfowler.com/eaaCatalog/transactionScript.html"&gt;Transaction Scripts&lt;/a&gt;&lt;em&gt;, and thus lose the advantages that the domain model can bring.” &lt;/em&gt;(Fowler)&lt;br/&gt;&lt;br/&gt;Some of the developers (very few) start asking questions about the consequences of not having true Domain model and what we could’ve changed to fix it. We came to the conclusion that more behavior driven design through interaction testing could’ve prevent that:&lt;br/&gt;&lt;br/&gt;&lt;em&gt;“One of the hardest things for people to understand in OO design is the &lt;/em&gt;&lt;a href="http://www.amazon.com/exec/obidos/ASIN/020161622X"&gt;"Tell Don't Ask" principle&lt;/a&gt;&lt;em&gt;, which encourages you to tell an object to do something rather than rip data out of an object to do it in client code. Interaction testers say that using interaction testing helps promote this and avoid the getter confetti that pervades too much of code these days.” &lt;/em&gt;(Fowler)&lt;br/&gt;&lt;br/&gt;However, this problem didn’t appeal to the rest of the developers as an important problem. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;2. Based on the complicated business logic, too many bugs were introduced because of not properly collaborating and encapsulated object in our model.&lt;/strong&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br/&gt;As the business logic growth in our application, we had too many defects and the implementation of the story cards was apparently harder and timelier to implement than before.&lt;br/&gt;This was as a direct consequence from the Transaction Script implementation of our business model. Yet, no any actions were taken.&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br/&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3.&amp;nbsp;&amp;nbsp; Problems with chaining&amp;nbsp;&amp;nbsp;of methods.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;em&gt;“Interaction-based testers do talk more about avoiding 'train wrecks' - method chains of style of &lt;span style="font-family:Courier New;font-size:85%;"&gt;getThis().getThat().getTheOther()&lt;/span&gt;. Avoiding method chains is also known as following the Law of Demeter. While method chains are a smell, the opposite problem of middle men objects bloated with forwarding methods is also a smell. (I've always felt I'd be more comfortable with the Law of Demeter if it were called the Suggestion of Demeter.)”&lt;/em&gt;(Fowler)&lt;br/&gt;&lt;br/&gt;I guess we had much more problems with chaining of methods than forwarding them. For our web application, we used web framework (&lt;a href="http://jakarta.apache.org/tapestry/"&gt;Tapestry&lt;/a&gt;), which binds the object to the view components in configuration file. As a consequence of the state base testing, we had a lot of “train wrecks”. Unfortunately, our IDEs (Eclipse, IntelliJ) couldn’t successfully refactor those “train wrecks” in those configuration files. One can imagine the consequences of that in a web base application.&lt;br/&gt;&lt;br/&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Test in isolation.&lt;/strong&gt;&lt;/li&gt;&lt;/ol&gt;&lt;em&gt;“If you introduce a bug to a system with interaction testing, it will usually cause only tests whose primary object contains the bug to fail. With a state-based approach, however, any tests of client objects can also fail, which leads to failures where the buggy object is used as a secondary object. As a result a failure in a highly used object causes a ripple of failing tests all across the system.” &lt;/em&gt;(Fowler)&lt;br/&gt;&lt;br/&gt;Not only that failing tests rippled through the whole application, but we had hangover cards because of problems with refactoring or JUST FIXING NOT PROPERLY WORKING METHODS. Since, we used state based testing style, we used to verify the consequence of some behavior rather verify the actual behavior. &lt;br/&gt;&lt;br/&gt;Example of this would be when we have an object that keeps some state. Let’s say that keeping the state in the proper form is major part of an application. Many operations lead to changes in the current state of this particular object. When we use state base testing, we don’t very that we change/revert/switch/override the state but rather we verify what is the state after performing some of these operation. &lt;br/&gt;&lt;br/&gt;As it usually happens, some of those methods weren’t implemented as the business wanted. After fixing them to work properly, the ripple effect of failing test all over the application was kind of awaking call. &lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Actions taken:&lt;/strong&gt;&lt;br/&gt;All these problems made our team think more in terms of &lt;a href="http://domaindrivendesign.org/book/"&gt;Domain Driven Design&lt;/a&gt;. We started having &lt;a href="http://bizdriven.blogspot.com/2005/10/domain-discussion.html"&gt;domain discussions&lt;/a&gt;. Also, we concentrate more on the collaboration and behavior of the objects in our &lt;a href="http://www.martinfowler.com/eaaCatalog/domainModel.html"&gt;Domain Model&lt;/a&gt;. We went back to the essential principles of OOP and start thinking more about behavior not so much about state.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Phase 3: Shifting from state based testing to more interactive style of testing.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Consequences:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1.&amp;nbsp;&amp;nbsp;Complex Fixture Setups&amp;nbsp;&amp;nbsp;&lt;/strong&gt;&lt;br/&gt;“&lt;em&gt;With state-based testing, you have to create all the objects that are going to be involved in responding to the stimulus. While the example only had a couple of objects, real tests often involve a large amount of secondary objects. Usually these objects are created and torn down with each run of the tests.&lt;/em&gt;&lt;br/&gt;&lt;em&gt;Interaction-based tests, however, only need to create the primary object and mocks for its immediate neighbors. This can avoid some of the involved work in building up complex fixtures.&lt;/em&gt;” (Fowler)&lt;br/&gt;&lt;br/&gt;As a consequence of building more sophisticated domain model and more complicated business logic, we started having a lot of complicated fixture setups. &lt;br/&gt;Of course we had “&lt;a href="http://www.xpuniverse.com/2001/pdfs/Testing03.pdf"&gt;Object Moder&lt;/a&gt;”, although we called it “&lt;strong&gt;Domain Fountain&lt;/strong&gt;” as more appropriate name in our test suites. However, we still had very complex setups since most of them were very concrete to a particular test.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Action taken:&lt;/strong&gt;&lt;br/&gt;As a result of that, we started substituting state based with interactive based testing. We set up and verified mocks all over the place. We used mocks almost everywhere when the set up was more complicated. Also, in this phase we liked the interactive based testing so much so that some developers refactored all previous tests that used dynamic mocks as stubs from not calling verify to call verify of the mock expectation. We clearly moved to the next phase.&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Phase 4: Accent on the interactive style of testing. Some initial steps towards Behavior Driven Design. &lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Consequences:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1. Coupling tests to implementation.&lt;/strong&gt;&lt;br/&gt;&lt;em&gt;“This coupling leads to a couple of concerns. The most important one is the effect on Test Driven Development. With interaction-based testing, writing the test makes you think about the implementation of the behavior - indeed interaction testers see this as an advantage. State-based testers however think that it's important to only think about what happens from the external interface and to leave all consideration of implementation until after you're done writing the test.”&lt;/em&gt;(Fowler).&lt;br/&gt;As Fowler pointed out, I think that this is an advantage. Since unit test is the clearest form of white/”window -(Rod Johnson)” box testing, I see interaction-based testing as the right thing to do. Also, in “pure” unit tests you should not be dependent on the implementation of the secondary objects as this is the case in state base testing.&lt;br/&gt;&lt;strong&gt;2. Using Mocks instead of Stubs.&lt;/strong&gt;&lt;br/&gt;This was one of the most painful mistakes that we did. We used mocks when we want to verify some expectation. However, we used mocks even when we didn’t care whether a particular method of a secondary object had been call. What is more, we used mocks instead of stubs in more than 80% of the cases.&lt;br/&gt;&lt;em&gt;“Coupling to the implementation also interferes with refactoring, since implementation changes are much more likely to break tests than with state-based testing.” &lt;/em&gt;(Fowler).&lt;br/&gt;As a direct consequence of that after every refactoring, we had very painful test fixing sessions. &lt;br/&gt;&lt;strong&gt;Phase 5: Behavior Driven Design with very careful consideration on Interactive based testing. &lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;1. Use Mocks only when we verify whether the behavior of the mock object has&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; been called. All other case, use stubs.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;In this phase, we use mocks only when we really need to verify the expectation. In all other cases, we use static stubs. In scenario like that, we don’t have problem of failing test when the implementation is fine, but some of mock expectations are not met. &lt;br/&gt;Using interactive based testing with more consideration will bring all the benefits of that kind of testing but will safe us a lot of troubles with refactoring.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2.&amp;nbsp;&amp;nbsp;Behavior Driven Design.&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;Since, we saw a huge damage on our OO design with using state base testing, we try to avoid this type of testing. Try having “one assert statement per test” (Astel).&lt;br/&gt;Anyway, this is much better explained in Dave Astel’s article about &lt;a href="http://daveastels.com/files/sdbp2005/BDD Intro.pdf"&gt;BDD&lt;/a&gt;.&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;Actions Taken:&lt;/strong&gt;&lt;br/&gt;I think that I would’ve been satisfied on this level. Unfortunately, our project ran out of time and we never really got to this last phase. … well, probably in the next project we can skip the first couple of phases. &lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;strong&gt;References Used:&lt;/strong&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;1. Fowler, Martin – Mocks aren’t Subs - &lt;a href="http://www.martinfowler.com/articles/mocksArentStubs.html"&gt;http://www.martinfowler.com/articles/mocksArentStubs.html#CouplingTestsToImplementations&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;2.&amp;nbsp;&amp;nbsp; Astels, Dave – Behavior Driven Development -&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href="http://daveastels.com/files/sdbp2005/BDD Intro.pdf"&gt;http://daveastels.com/files/sdbp2005/BDD Intro.pdf&lt;/a&gt; &lt;br/&gt;3.&amp;nbsp;&amp;nbsp;Wikipedia – Unit Tests -&amp;nbsp;&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;http://en.wikipedia.org/wiki/Unit_testing&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113073784786640246?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/10/stubs-or-mocks-state-or-behavior_30.html' title='Stubs or Mocks - State or Behavior - Testing or Design: Evaluated!'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113073784786640246/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113073784786640246&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113073784786640246'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113073784786640246'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/10/stubs-or-mocks-state-or-behavior_30.html' title='Stubs or Mocks - State or Behavior - Testing or Design: Evaluated!'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-113046521306473431</id><published>2005-10-27T21:06:00.000-05:00</published><updated>2005-10-27T21:52:22.300-05:00</updated><title type='text'>Stubs or Mocks - State or Behavior  - Testing or Design</title><content type='html'>A colleague of mine, &lt;a href="http://bizdriven.blogspot.com/"&gt;Siva&lt;/a&gt; post a short blog entry &lt;a href="http://bizdriven.blogspot.com/2005/10/mocks-are-evil.html"&gt;Mocks are evil!&lt;/a&gt;&lt;strong&gt;, &lt;/strong&gt;which became very interesting debate about OO programming and design, how we thing about verifying and designing our objects as well as the standard argument about Mocks or Stubs. I think that it is very interesting debate that I will repost on my blog as well. Siva is arguing that using Mocks is not always the best thing to do. I completely agree with that but I disagree about the importance of state testing for good OOD.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Siva said: &lt;/strong&gt;&lt;a href="http://bizdriven.blogspot.com/2005/10/mocks-are-evil.html"&gt;Mocks are evil!&lt;/a&gt;&lt;strong&gt; &lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;-------------------------------------------------------------------------------------------------&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Igor said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This could be seen in two ways:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;1) We are testing the implementation rather than verifying behavior. &lt;/em&gt;&lt;br /&gt;&lt;br /&gt;And this is exactly what we do. Example, my method should call dao in order to persist to db. I don’t want to know if we actually persist the object, I just want to now whether particular method of the INTERFACE of the dao is called. Interface identifies behavior. That’s why I want to verify this behavior.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;2) As our interactive based tests are tied to implementation, refactoring becomes a pain. Refactoring will take more time as we need to fix interactive based tests.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;Since we don’t care about the actual implementation of the method, this could save us a lot of troubles when we change, refractor or substitute different objects (implementation) for the tested interface method. If we have problems with the mocks when we refractor, this means, the behavior has changed and that is what we are testing. If we don’t care about the behavior then we are probably better off with stubs.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;3) It puts us in wrong perspective. Instead of thinking in terms of behaviors in our unit (tests / contexts) we end up thinking about implementation like whether this method calls that method.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;If you use real object, then you think about the state of this object and not for their behavior, which is no any different than thinking about db tables.&lt;br /&gt;&lt;br /&gt;Otherwise, I feel your pain. Probably, we should use them more rationally.&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Siva Jagadeesan said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;I don’t want to know if we actually persist the object, I just want to now whether particular method of the INTERFACE of the dao is called.&lt;br /&gt;&lt;br /&gt;Igor I accept with u. This above scenario is a good example for interactive based testing.&lt;br /&gt;&lt;br /&gt;Take this code snippet for example.&lt;br /&gt;&lt;br /&gt;public void doSomethingAndSave(){&lt;br /&gt;doSomething();&lt;br /&gt;getDao().save();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;For the above method, we might have these following behaviors to verify.&lt;br /&gt;&lt;br /&gt;Behavior 1) shouldCallDaoSave&lt;br /&gt;Behavior 2) shouldDoSomething&lt;br /&gt;&lt;br /&gt;Behavior 1 is perfect for using interactive based testing. By using mock we could avoid going to database.&lt;br /&gt;&lt;br /&gt;In behavior 2, we do not care whether it is calling getDao().save(), all we want to verify is whether it is doing “something" that we specify. In this situation state based testing is better than interactive based testing. By using dummy stubs, we do not have to change this behavior even if we decide not save anything after doing “something”. But if we used interactive based testing for this behavior, then we would have to fix this behavior (even though nothing has changed in behavior that it specifies) when we refactor this method not to save anything.&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Igor said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;In 1) you are interested in how the dao will behave. That’s when you need a mock to verify its behavior as you pointed out.&lt;br /&gt;&lt;br /&gt;In 2) you have behavior specification that tests exactly “doSomethingElse”. So, in this case you don’t need to mock dao because you don’t verify its behavior. You should have one assert/verification per test, so you testing/verifying the dao at all. You just need to stub it. However, I don’t think that state testing has anything to do with this situation. If you stub it, you don’t check for the state at all.&lt;br /&gt;&lt;br /&gt;I believe that state testing is not good approach to OO design. It makes us think in terms of data holders (aka db tables) instead of thinking about object behavior and object collaboration. Since, one of the principles of OOP is hiding the state of the object and providing specific behavior, we should avoid thinking of the state of the object. That’s one of the major reason why most of the object that we see are data holders with public getters and setters. I would prefer to see object without any public getter or setter rather with methods giving me some behavior.&lt;br /&gt;&lt;br /&gt;So in summary, I completely agree that we should use mock with great deal of consideration. Also, most of the times stubs would be more appropriate. Yet, don’t confuse using stubs with state testing. I completely disagree that state testing can be any good for OOP.&lt;br /&gt;&lt;br /&gt;----------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Siva Jagadeesan said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Igor I agree with you :)&lt;br /&gt;&lt;br /&gt;Quote from Martin’s article about state based testing,&lt;br /&gt;&lt;br /&gt;“…kick your primary object with the behavior you want to test. Once it's done you then need to find out if everything went well. This you probe by using a bunch of assert statements, both against the primary object…”&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.martinfowler.com/articles/mocksArentStubs.html%23State-basedTesting"&gt;http://www.martinfowler.com/articles/mocksArentStubs.html#State-basedTesting&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In my article I am not advocating State based testing… I am more concerned about verifying behavior of an object. How we verify behavior depends on framework we use. If we use Junit, unfortunately we have to verify behavior by asserting the state of object.&lt;br /&gt;&lt;br /&gt;I have not looked at JBehave, it will be interesting to see how this framework enables us to verify the behavior of object.&lt;br /&gt;&lt;br /&gt;------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Igor said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Martin’s article is classic but it is a little outdated already. As I pointed out, I don’t think that state base testing brings value for creating good OOD. (Probably for QA testing yes, but not designing).&lt;br /&gt;&lt;br /&gt;You can use JUnit with EasyMock or JMock and verify behavior without any problem. It is not design to verify behavior but with a little more effort you can achieve Behavior Driven Design with JUnit as well.&lt;br /&gt;&lt;br /&gt;I agree on everything else besides the testing of the state of an object. Since the state should be encapsulated inside of the object, I don’t think that trying to test it will evolve to a good Object Oriented Design. You shouldn’t be allowed to ask an object for its state; rather you should delegate some responsibility to an object and verify whether it perform it correctly.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;----------------------------------------------------------------------------------------------------&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Siva Jagadeesan said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;You can use JUnit with EasyMock or JMock and verify behavior without any problem. It is not design to verify behavior but with a little more effort you can achieve Behavior Driven Design with JUnit as well.&lt;br /&gt;Using EasyMock or JMock with Junit , we will be still testing implementation not the behavior.&lt;br /&gt;&lt;br /&gt;I agree on everything else besides the testing of the state of an object. Since the state should be encapsulated inside of the object, I don’t think that trying to test it will evolve to a good Object Oriented Design. You shouldn’t be allowed to ask an object for its state; rather you should delegate some responsibility to an object and verify whether it perform it correctly.&lt;br /&gt;&lt;br /&gt;Lets take classic object Lamp.&lt;br /&gt;public class Lamp {&lt;br /&gt;private boolean on;&lt;br /&gt;public void switchOn(){&lt;br /&gt;setOn(true);&lt;br /&gt;}&lt;br /&gt;public boolean isOn() {&lt;br /&gt;return on;&lt;br /&gt;}&lt;br /&gt;private void setOn(boolean on) {&lt;br /&gt;this.on = on;&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;Might be I am missing something here. How can we make sure “switchingOn” behavior worked correctly without verifying the state (on/off) of Lamp?&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Igor said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This example is very similar to the problem that they describe in famous article about OOD - “The Mark IV Special Coffee Maker”. &lt;a href="http://www.objectmentor.com/resources/articles/resources/resources/articles/CoffeeMaker.pdf"&gt;http://www.objectmentor.com/resources/articles//resources/resources/articles/CoffeeMaker.pdf&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We are writing a program here, and programs are about behavior! We should think about behavior. What is the behavior in class Light? It is the behavior of a system that is the first clue to how the software should be partitioned.&lt;br /&gt;&lt;br /&gt;Clearly, from you design the Light object just wants to be turned on or turned off. Thus we might put :&lt;br /&gt;&lt;br /&gt;void switchOn();&lt;br /&gt;void switchOff()&lt;br /&gt;&lt;br /&gt;method in class Light. I think that the return value of these methods is the problem here.&lt;br /&gt;So, if the behavior that you want is to swtichOn the light and then verify that everything went successfully:&lt;br /&gt;&lt;br /&gt;public interface Switchable{&lt;br /&gt;boolean switchOn();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Lamp implements Switchable {&lt;br /&gt;public boolean switchOn(){&lt;br /&gt;  //implementation that we don’t care&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Behavior Specification will look like this.&lt;br /&gt;&lt;br /&gt;public void shouldSitchOnTheLightSuccesfullyWhenEverythingIsOk(){&lt;br /&gt;Ligh light = new Light();&lt;br /&gt;shouldBeSuccessfull(ligh.switchOn());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;That’s it. I don’t need to check the state of the light in order to verify that the behavior specification of this object.&lt;br /&gt;&lt;br /&gt;Later on, if you need additional behavior to check whether the light is on you can add the other method:&lt;br /&gt;&lt;br /&gt;public boolean isOn();&lt;br /&gt;&lt;br /&gt;However, do you really want to know that? I would try to avoid this method since “One of the core tenets of object-oriented programming is encapsulation. It’s one of OO’s most powerful ideas. More powerful than inheritance. Unfortunately it’s also one of the most ignored.” From Dave Astels’s blog: &lt;a href="http://blog.daveastels.com/?p=55"&gt;http://blog.daveastels.com/?p=55&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you put isOn() method just to test switchOn() without actually needing it then you reveal to much from your code without needing it. From the pragmatic guys &lt;a href="http://www.pragmaticprogrammer.com/articles/may_04_oo1.pdf"&gt;http://www.pragmaticprogrammer.com/articles/may_04_oo1.pdf&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;“The best code is very shy. Like a four-year old hiding behind a mother’s skirt, code shouldn’t reveal too much of itself and shouldn’t be too nosy into others affairs.&lt;br /&gt;But you might find that your shy code grows up too fast, shedding its demure shyness in favor of wild promiscuity. When code isn’t shy, you’ll get unwanted coupling.”&lt;br /&gt;&lt;br /&gt;Your testing and behavior specification are tightly coupled to the implementation of Light object. “This is a classic approach from the old days or procedural programming. It is NOT OO. This is just one example of the approach of treating objects like new age data structures: Ask an object for information about its state, process that, make decisions based on that, then do something to/with the object.” (Astel’s)&lt;br /&gt;&lt;br /&gt;All we should know is how to ask the light to turn on and whether it went successfully.&lt;br /&gt;The proper approach is to ask the Light to turn itself on. Let me know if you were able to do that. We don’t care about it state at all.&lt;br /&gt;&lt;br /&gt;This is a little aside but:&lt;br /&gt;&lt;br /&gt;“As a side note, writing code this way makes it much more understandable.” (Astel’s)&lt;br /&gt;&lt;br /&gt;Also, from Dave Astele’s brilliant article about Behavior Driven Design (BDD) &lt;a href="http://daveastels.com/files/sdbp2005/BDD%20Intro.pdf"&gt;http://daveastels.com/files/sdbp2005/BDD%20Intro.pdf&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;“First stop thinking in terms of tests. As Bob Martin has been saying for a few years “Specification, not Verification”. What Bob means is that verification (aka testing) is all about making sure (i.e. verifying) that your code functions correctly while specification is all about defining what it means (i.e. specifying) for your code to function correctly.”&lt;br /&gt;&lt;br /&gt;So based on the above, if you argue that in my behavior specification I would not be sure whether the light is actually turned on right now (verify that my code works correctly), I would say that I just want to now that light has been turned on successfully (not exactly interested if it is on right now.)&lt;br /&gt;&lt;br /&gt;Anyway, this debate is going on for the last 10-12 years of OOP, so I think will continue have arguments about that. Still, if we care about the state than what is the difference between OOP and database.&lt;br /&gt;&lt;br /&gt;-----------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Siva Jagadeesan said... &lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Igor it is a great explanation. I think my problem is my state of mind. Even though I am familiar with OOP concepts, I am relaxing those OOP rules to make it testable. This is wrong. I should consciously do behavior driven design.&lt;br /&gt;&lt;br /&gt;Instead of State Based Testing, how about Behavior Based Testing?&lt;br /&gt;&lt;br /&gt;---------------------------------------------------------------------------------------------------------&lt;br /&gt;&lt;strong&gt;Igor said…&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;P.S. &lt;/strong&gt;After Siva contacted Martin Fowler about all that, he stated that he is still unconvinced about this style of testing since mock verification couple a test to the implementation of the object under test. So, I have to say the article “Mocks aren’t Stubs”, from which I learned a great deal about design and testing as a whole is not outdated. Rather, my view about object state testing has changed a lot since I read this invaluable article and I tend to have different opinion on that now.&lt;br /&gt;&lt;br /&gt;Thanks to Martin for his significant input on that topic and his replay.&lt;br /&gt;Siva, thanks for the interesting topic and exciting debate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-113046521306473431?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/10/stubs-or-mocks-state-or-behavior.html' title='Stubs or Mocks - State or Behavior  - Testing or Design'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/113046521306473431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=113046521306473431&amp;isPopup=true' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113046521306473431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/113046521306473431'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/10/stubs-or-mocks-state-or-behavior.html' title='Stubs or Mocks - State or Behavior  - Testing or Design'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-111388190592682302</id><published>2005-04-18T22:37:00.002-05:00</published><updated>2009-02-22T23:02:40.416-06:00</updated><title type='text'>Spring Framework Overview</title><content type='html'>&lt;p class="MsoNormal" style="font-weight: bold;"&gt;Achieving better object oriented design and ability to use TDD by using Lightweight containers.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;span style="font-weight: normal;"&gt;by Igor Stoyanov&lt;/span&gt;.&lt;/p&gt; &lt;p class="MsoNormal"&gt;Many J2EE web applications contain too much code in the web tier. There are various reasons for this, but I think the most important are:&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: -0.25in; margin-left: 0.5in;"&gt;-&lt;span style="font-style: normal; font-variant: normal; font-weight: normal;font-family:Times New Roman;font-size:7;"&gt;         &lt;/span&gt;Too few books emphasize the importance of a thin web tier. There are many books discussing MVC frameworks, emphasizing on the importance of properly designed web tier, separating control logic from presentation logic but much less of how the web tier should related to the rest of the application.&lt;/p&gt;    &lt;p class="MsoNormal" style="text-indent: -0.25in; margin-left: 0.5in;"&gt;-&lt;span style="font-style: normal; font-variant: normal; font-weight: normal;font-family:Times New Roman;font-size:7;"&gt;         &lt;/span&gt;There are many web frameworks but there’s no framework for business  objects.&lt;/p&gt;&lt;p class="MsoNormal" style="text-indent: -0.25in; margin-left: 0.5in;"&gt;-&lt;span style="font-style: normal; font-variant: normal; font-weight: normal;font-family:Times New Roman;font-size:7;"&gt;         &lt;/span&gt;Putting business logic in the web tier is often perceived as the quickest path to a solution. The previous point helps to understand the cause of this common misconception. However, it is a misconception, as working with a more sophisticated architecture will quickly show.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Until recently, the only framework that addresses partially some of these issues was EJB. Although, there are many problems and complexity related to using EJB, this was the primary framework for managing business tier objects. There are many nice thing specified in EJB such as declarative transaction in container management of business object, scalable remote architecture, very fine grained declarative security. However, the complexity of implementation, problems with performs in some cases, difficulties to test and too much overhead form majority of J2EE applications cause the emergence of lightweight container for managing business transaction. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;The most popular lightweight containers are &lt;a href="http://www.springframework.org/" style="color: blue; text-decoration: underline;"&gt; Spring framework&lt;/a&gt;, &lt;a href="http://www.picocontainer.org/" style="color: blue; text-decoration: underline;"&gt; Pico container&lt;/a&gt; and &lt;a href="http://jakarta.apache.org/hivemind/" style="color: blue; text-decoration: underline;"&gt; HaveMind&lt;/a&gt;. These lightweight containers take some of the successful ideas from EJB to bring a greater level of sophistication to non-EJB architectures. They are similar to EJB arhcitecures in being centered around a layer of managed business service object. However, this is where the similarity ends. Instead of running inside an EJB container, business objects run inside a lightweight container. Lightweight containers aren’t tied to J2EE, have negligible startup cost and eliminate the deployment step of EJB. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;The beauty of lightweight containers is that the business objects that they manage are POJO running inside of the containers. They are managed via AOP interception to deliver enterprise services. Unlike EJBs, they don’t usually need to depend on container APIs, meaning that they are also usable outside any container. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;All these factors make lightweight containers the preferable choice if using Agile Methodologies together with TDD. According to agile, the design and implementation should be driven by the business requirements not by unnecessary complex specifications that have to be implemented. According to TDD, this is currently the only choice in order to achieve superior design and quality of the software application. This is of course if you have the freedom to choose technologies to work with. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;I will look more closely at the currently most advanced lightweight container – Spring Framework. There are so many things that Spring Frameworks provides to make development easier that it is very hard to be described or summarized. I will talk about the most important of ones:&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;- &lt;b&gt;Interface-implementation Separation&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;EJB enforces a separation between interface (component interface of business methods interface) and implementation (bean implementation class). This is actually one of the best things in EJB, as programming against interfaces rather than classes is a best practice with many beneficial consequences, such as “pluggability”.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;Most lightweight containers do not enforce such a separation. However, they do recommend doing it, but in my experience, giving more freedom to developers doesn’t always provide better results. At least in this situation, I would rather prefer EJB approach of enforcing implementation against interfaces. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;- &lt;b&gt;Inversion of Control (IoC)&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Most business objects have dependencies, such as other business objects, data access objects and resource. Because of that, there is a need to look up other managed object and resource, and therefore must dependent on a container to satisfy that. In satisfying this look up services lies the major difference between EJBs and lightweight containers as Spring framework. Both architectures achieve this look up service by Inversion of Control (IoC). The difference is that EJB architecture implements IoC with Dependency Lookup opposed to Spring framework, which implements IoC with Dependency Injection. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; &lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;b&gt;- Declarative Transaction Management&lt;/b&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;This is almost similar to EJBs architecture. The difference is that Spring frameworks provides much finer grained transaction management and much more flexibility in specifying transaction strategy.&lt;br /&gt;&lt;/p&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_7aYqj-OFwPA/SaIs9_WL_vI/AAAAAAAAAQ0/ZxzKE42Y3dY/s1600-h/inversion_of_control.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_7aYqj-OFwPA/SaIs9_WL_vI/AAAAAAAAAQ0/ZxzKE42Y3dY/s400/inversion_of_control.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5305852754484002546" /&gt;&lt;/a&gt;&lt;p&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;The next diagram illustrates a typical Spring framework web application architecture. The Spring architecture is conceptually similar to the “local EJB architecture”. However, it tends to work out very differently in Practice.&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_7aYqj-OFwPA/SaItYTu-8tI/AAAAAAAAAQ8/87xLntDvVhU/s1600-h/spring_layers.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_7aYqj-OFwPA/SaItYTu-8tI/AAAAAAAAAQ8/87xLntDvVhU/s400/spring_layers.gif" border="0" alt="" id="BLOGGER_PHOTO_ID_5305853206633312978" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal"&gt;&lt;b style=""&gt;&lt;span style="font-size:14;"&gt;Reference:&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Example application using Strust and Spring could be found at:&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://www.onjava.com/pub/a/onjava/excerpt/BFLJava_chap8/"&gt;http://www.onjava.com/pub/a/onjava/excerpt/BFLJava_chap8/&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Explanation of how Spring handles multithreading at (very good):&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://www.javalobby.org/articles/thread-safe/index.jsp"&gt;http://www.javalobby.org/articles/thread-safe/index.jsp&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Example simple application using Strust+Spring+Hibernate(should probably start from here):&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=1"&gt;http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=1&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Many useful materials can be found at AppFuse project: &lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;a href="http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse"&gt;http://raibledesigns.com/wiki/Wiki.jsp?page=AppFuse&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;Of course, there are lots of materials and examples at &lt;a href="http://www.springframework.org/"&gt;www.springframework.org&lt;/a&gt;&lt;/p&gt;  &lt;p class="MsoNormal"&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-111388190592682302?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/04/spring-framework-overview.html' title='Spring Framework Overview'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/111388190592682302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=111388190592682302&amp;isPopup=true' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111388190592682302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111388190592682302'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/04/spring-framework-overview.html' title='Spring Framework Overview'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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://3.bp.blogspot.com/_7aYqj-OFwPA/SaIs9_WL_vI/AAAAAAAAAQ0/ZxzKE42Y3dY/s72-c/inversion_of_control.gif' height='72' width='72'/><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6178209.post-111379680725448697</id><published>2005-04-17T22:30:00.000-05:00</published><updated>2005-10-18T23:53:42.696-05:00</updated><title type='text'>Test Driven Development TDD</title><content type='html'>&lt;p class="MsoNormal" style=""&gt;&lt;span style="font-weight: bold;"&gt;Impact of Test Driven Development together with test automation on the software design.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal" style=""&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;by Igor Stoyanov.&lt;/span&gt;&lt;a href="mailto:igor@thoughtworks.com"&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt; &lt;span style=""&gt; &lt;/span&gt;  &lt;p class="MsoNormal" style=""&gt;I have already mentioned &lt;b style=""&gt;test driven development&lt;/b&gt; &lt;b style=""&gt;(TDD) &lt;/b&gt;in &lt;a href="http://igorstoyanov.blogspot.com/2005/04/continuous-integration.html"&gt;previous post&lt;/a&gt; on this blog.&lt;b style=""&gt; &lt;/b&gt;This is often also referred to as &lt;b style=""&gt;test first development&lt;/b&gt;.I am TDD practitioner myself, and recommend it highly. Although, some of the other XP techniques can be strongly debatable, I believe that TDD development and continues integrations are mandatory methodologies for the success of a software project today.&lt;span style=""&gt;  &lt;/span&gt;From being the poor cousin of development, the &lt;b style=""&gt;unit testing&lt;/b&gt; - has become welcomed as the heart of the software development. &lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;TDD brings many benefits. For example:&lt;/p&gt;   &lt;ul&gt;&lt;li&gt;It is the best way of achieving &lt;b style=""&gt;comprehensive test coverage&lt;/b&gt;. Retrofitting test to existing code doesn’t produce quality test and it is not exciting at all for developers.&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;Writing test along with the application code can helps to define the requirements on each class. Theirs is nothing like writing a test first to make think about &lt;b style=""&gt;requirements of a method&lt;/b&gt;. What should it do on null argument? Should it return null or throw an exception. &lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;Having comprehensive test suite gives us &lt;b style=""&gt;effective regression testing&lt;/b&gt;. We can add new functionality and even more importantly, have the courage to &lt;b style=""&gt;refactor&lt;/b&gt; existing code (an essential ability in order to have clean and maintainable code base).&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;It helps you write the &lt;span style="font-weight: bold;"&gt;simplest possible code&lt;/span&gt;. We don’t need to write complex code until we have a test that proves it’s required. If we continue, we can’t have a test that proves it until we have clear business need for that reflected in the story card requirements.&lt;span style=""&gt;  &lt;/span&gt;In my opinion, this has the most beneficial reflection over designing clearer, readable and more maintainable code.&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;TDD means that developers have &lt;span style="font-weight: bold;"&gt;constant feedback&lt;/span&gt; about progress in the form of more and more passing test demonstrating required functionality. This is very satisfying.&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;In my opinion, using TDD is much &lt;span style="font-weight: bold;"&gt;more fun and fulfilling&lt;/span&gt;. &lt;/li&gt;&lt;/ul&gt;      &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;There are plenty that can be added to this topic. Good resources on this topic is this excellent blog: &lt;a href="http://www.testing.com/cgi-bin/blog"&gt;Exploration Through Example&lt;/a&gt;, the book &lt;a href="http://www.amazon.com/exec/obidos/tg/detail/-/0131016490/103-1183695-7357451?v=glance"&gt;“Test-Driven Development – A Practical Guide”&lt;/a&gt; by &lt;st2:personname&gt;&lt;st1:givenname&gt;David&lt;/st1:givenname&gt;  &lt;st1:sn&gt;Astels&lt;/st1:sn&gt;&lt;/st2:personname&gt; as well as very good and important book &lt;a href="http://www.amazon.com/exec/obidos/ASIN/0764558315/qid=1113885244/sr=2-1/ref=pd_bbs_b_2_1/103-1183695-7357451"&gt;"J2EE Development withoug EJB"&lt;/a&gt; by Rod Johnson.&lt;br /&gt;&lt;/p&gt;      &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;It is not the most intuitive thing to test something that doesn’t exist. In order to become comfortable with TDD you should start practicing with full believe and fully apply this methodology. Very soon, the benefit would be very obvious. It is simple concept, but I need some working example in order to fully realize the power of TDD approach. &lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;I will briefly summarize the most important steps in TDD development and demonstrate a very simple example.&lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;The most important characteristic in TDD are:&lt;/p&gt;     &lt;ul&gt;&lt;li&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Create a test case to test business driven functionality.&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;Test against interface methods, which could be generated using IDE support.&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Using interfaces is one the best Object Oriented principal and lead to very good overall design. Furthermore, testing against interfaces allows us to use mock object in our unit testing. Using mock objects can improve our unit testing and improve the performance of the test suite. It is very important that the tests run comparably fast because one of their purposes is to give constant and fast feedback to developers. Another advantage of using mock objects is that your test is more accurate and allows truly unit testing.&lt;span style=""&gt;  &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Always, always make the &lt;b style=""&gt;&lt;span style="color: rgb(255, 102, 0);"&gt;test to fail first&lt;/span&gt;&lt;/b&gt;. This is very important and often forgotten in practice. My experience has shown me that many times tests pass even if they are wrong. You should make sure that a test fails first in order to be sure everything is alright when the next time the same test pass. &lt;/li&gt;&lt;/ul&gt;   &lt;ul&gt;&lt;li&gt;&lt;span style=""&gt;&lt;span style=""&gt;&lt;/span&gt;&lt;/span&gt;Write &lt;b style=""&gt;negative test first&lt;/b&gt;. This is a test that verifies behavior beside the normal path of execution. Example of that could be data access exception during DAO testing or what happens if a required parameters has not been initialized. Such scenarios are hard to reproduce in a deployment environment, and hence hard to cover in component and integration testing.&lt;span style=""&gt;  &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;Before a demonstration of TDD with a simple test case, I want to mention here that in order for TDD to have the desired effect, developers should create pure unit test. The most popular and sufficient Java framework is JUnit. The design and the decision for technologies that will be used should be strongly impact by the fact whether it is easily testable and in some cases, if it is testable at all. I want to add immediately here that no test can prove full coverage and suffice by itself for good testing approach to a particular application. A TDD development implies that developers are mainly involved in unit testing, also known as white testing. Continues integration testing and rigorous functional testing are invaluable testing approaches but they should not be primarily responsibility of developers. &lt;span style=""&gt; &lt;/span&gt;&lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;As a practitioner of TDD I wouldn’t choice working with EJB technology if I have other valuable alternatives. EJB are managed during runtime by EJB container. Its development is not only very complex but it very hard, and in some cases (Entity Beans) it is almost impossible to test, not to mention that TDD is unthinkable. Attempts are made to solve this problem with EJB mocks, which is not very successful and using in container testing frameworks as Cactus. Although, using Cactus is irreplaceable for integration in container testing of EJB, it can not be used for pure unit testing. As I mentioned before, unit testing should provide very fast feedback to a developer in order to be useful. Using cactus as unit testing implies that for testing of even single method, we should wait for deployment and very complex initializing operations of the targeted container before we have a feedback. Not to mention the complexity of setting up Cactus framework on the firs place. &lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt;&lt;/o:p&gt;Luckily, lightweight containers come to rescue. Using these lightweight containers involves primarily the use of POJO objects that are the easiest to test and can lead to the best OO design of a given software project. The most popular ones are &lt;a href="http://www.springframework.org/"&gt;Spring framework&lt;/a&gt; and &lt;a href="http://www.picocontainer.org/"&gt;Pico container&lt;/a&gt;. I will talk much more about these containers a little later on. &lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;br /&gt;TDD demonstration: &lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;Requirements:&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;  &lt;/span&gt;&lt;b style=""&gt;Business functionality&lt;/b&gt;&lt;i style=""&gt;:&lt;/i&gt; &lt;i style=""&gt;Withdrawal&lt;o:p&gt;&lt;/o:p&gt;&lt;/i&gt;&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;b style=""&gt;&lt;i style=""&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;span style=""&gt; &lt;/span&gt;&lt;/i&gt;Can anticipate&lt;/b&gt;: - &lt;i style=""&gt;Refusing access to data storage&lt;/i&gt; &lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;                                   &lt;/span&gt;- &lt;i style=""&gt;Insufficient Funds in the account&lt;/i&gt; &lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;   &lt;/span&gt;&lt;b style=""&gt;Prerequisites&lt;/b&gt;:&lt;span style=""&gt;   &lt;/span&gt;- &lt;i style=""&gt;There is an existing account &lt;/i&gt;(I am really hoping for. &lt;span style="font-family:Wingdings;"&gt;&lt;span style=""&gt;J&lt;/span&gt;&lt;/span&gt;.)&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;                                   &lt;/span&gt;- &lt;i style=""&gt;The account can accept deposits&lt;/i&gt;. &lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;span style=""&gt;                                  &lt;/span&gt;- &lt;i style=""&gt;The account knows the current balance.&lt;br /&gt;&lt;/i&gt;&lt;/p&gt; &lt;p class="MsoNormal" style=""&gt;Targeted test code:&lt;br /&gt;&lt;/p&gt; &lt;p class="MsoNormal" style=""&gt;public &lt;span style="color: rgb(0, 0, 0);"&gt;class&lt;/span&gt; BankAccountTest extends TestCase {&lt;br /&gt;    private BankAccount account;&lt;/p&gt; &lt;p class="MsoNormal" style=""&gt;    protected void setUp() throws Exception {&lt;br /&gt;            account = new BankAccount();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void testValidWithdrawalSuccedsWithinLimit() throws DataAccessException,&lt;br /&gt;                                                                                                                InsuffiecientFundsException {&lt;br /&gt;            account.setBalance(45.0);&lt;br /&gt;            account.withdrawal(20.0);&lt;br /&gt;            assertEquals(25.0, account.getBalance());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public void testNotValidWithdrawalFailOutsideLimit() throws DataAccessException{&lt;br /&gt;            try {&lt;br /&gt;                account.setBalance(45.0);&lt;br /&gt;                account.withdrawal(46.0);&lt;br /&gt;                fail("Bank should have rethrown InsufficientFundsExcepiton");&lt;br /&gt;           }catch(InsuffiecientFundsException ex) {&lt;br /&gt;                assertEquals("Correctly calcualted amount fo unapproved overdraft",1.0,                          ex.getShorfail());&lt;br /&gt;          }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-111379680725448697?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/04/tdd-methodology.html' title='Test Driven Development TDD'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/111379680725448697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=111379680725448697&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111379680725448697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111379680725448697'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/04/test-driven-development-tdd.html' title='Test Driven Development TDD'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-111378852495509882</id><published>2005-04-17T20:39:00.000-05:00</published><updated>2005-10-18T23:55:29.166-05:00</updated><title type='text'>Agile Development</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Reflecting the use of Agile Methodologies on overall Server Side Design and Development&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;by Igor Stoyanov.&lt;/span&gt;&lt;span style="text-decoration: underline;"&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="text-decoration: underline; font-style: italic;"&gt;&lt;/span&gt;&lt;a href="mailto:igor@thoughtworks.com"&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p class="MsoNormal" style=""&gt;Agile methodologies are alternative approach to the traditional &lt;b style=""&gt;Engineering Methodologies&lt;/b&gt;. The most immediate difference is that they are less document-oriented, usually emphasizing a smaller amount of documentation for a given task. In many ways they are rather code-oriented: following a route that says that the key part of documentation is source code. However, a more precise picture could be drawn with a short excerpt from the article &lt;a href="http://www.martinfowler.com/articles/newMethodology.html#N10058"&gt;“The New Methodology”&lt;/a&gt; written by one of the founders of &lt;a href="http://www.agilemanifesto.org/"&gt;Agile Manifesto&lt;/a&gt;, &lt;a href="http://www.martinfowler.com/"&gt;Martin Fowler&lt;/a&gt;:&lt;/p&gt;   &lt;ul type="disc"&gt; &lt;li class="MsoNormal" style=""&gt;&lt;i&gt;Agile methods are adaptive      rather than predictive.&lt;/i&gt; Engineering methods tend to try to plan out a large part of the software process in great detail for a long span of time, this works well until things change. So their nature is to resist change. The agile methods, however, welcome change. They try to be processes that adapt and thrive on change, even to the point of changing themselves. &lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;&lt;i&gt;Agile methods are      people-oriented rather than process-oriented.&lt;/i&gt; The goal of engineering methods is to define a process that will work well whoever happens to be using it. Agile methods assert that no process will ever make up the skill of the development team, so the role of a process is to support the development team in their work.&lt;/li&gt; &lt;/ul&gt;   &lt;p class="MsoNormal" style=""&gt;The rest of this article is invaluable information about Agile Methodologies and there are many references to related links and materials. I will strongly suggest reading this article if you are interested in Agile Methodologies. &lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;However, my purpose is not to do and overview of Agile Methodologies rather than I will look at only a few aspects of agile that I believe have very strong influence on the overall software design during software development of a business driven project.&lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;Agile development is characterized mainly by using two to four weeks iterations. In the beginning of every iteration, the team commits to deliver some number of story cards. A story card is similar to the user cases defined in traditional software engineering process. The main and very essential difference that story cards has limited set of functionality so that the team can deliver it at the end of the iteration. Furthermore, everything in the story card should be driven by the business requirements. &lt;span style=""&gt; &lt;/span&gt;&lt;/p&gt;     &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;This methodology influences the software design in the following two very essential ways:&lt;/p&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/p&gt;   &lt;ol style="margin-top: 0in;" start="1" type="1"&gt; &lt;li class="MsoNormal" style=""&gt;The team is committed to deliver working product at the end of the iteration – avoid 80:20 problem in software development.&lt;/li&gt;&lt;li class="MsoNormal" style=""&gt;Develop functionality that is only business needed driven – doesn’t over design the current systems and produce much cleaner and maintainable code base.&lt;/li&gt; &lt;/ol&gt;   &lt;p class="MsoNormal" style=""&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;span style=";font-family:georgia;font-size:12;"  &gt;There are many more consequences to add, but all other essential ones are summarized in &lt;a href="http://www.extremeprogramming.org/"&gt;XP&lt;/a&gt; development process, which is a subset of agile methodologies by itself&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-111378852495509882?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/04/agile-development.html' title='Agile Development'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/111378852495509882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=111378852495509882&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111378852495509882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111378852495509882'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/04/agile-development.html' title='Agile Development'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-111362148451945121</id><published>2005-04-15T22:15:00.000-05:00</published><updated>2005-09-11T23:37:44.490-05:00</updated><title type='text'>Continuous Integration</title><content type='html'>&lt;b&gt;Unit, Integration and Container testing using JUnit,  Cactus and Ant frameworks&lt;br /&gt;&lt;br /&gt;&lt;/b&gt; &lt;p class="MsoNormal"&gt;&lt;span style="font-style: italic;"&gt;by Igor Stoyanov.&lt;/span&gt;&lt;a href="mailto:istoyan@cs.luc.edu" style="color: blue; text-decoration: underline;"&gt;&lt;/a&gt;&lt;/p&gt;   &lt;p class="MsoNormal"&gt;A strong principle of &lt;i&gt;eXtreme Programming&lt;/i&gt; (XP) is  the continuous integration aspect (see the &lt;a href="http://www.martinfowler.com/articles/continuousIntegration.html" title="" style="color: blue; text-decoration: underline;"&gt; Continuous Integration&lt;/a&gt; article by Martin Fowler). The traditional approach to the development of complex software has been to separate the development process into phases of coding, testing and integration. The continuous integration principle is to basically code, test and integrate at the same time, so that at almost any point in time, you have a working product. &lt;/p&gt;  &lt;p&gt;In order to achieve this, you need to be able to automatically build your entire application, including running the unit and acceptance tests. Thus, tools such as &lt;a href="http://ant.apache.org/"&gt;Ant &lt;/a&gt;or &lt;a href="http://maven.apache.org/" title="" style="color: blue; text-decoration: underline;"&gt; Maven&lt;/a&gt; are the foundation for continuous integration.&lt;/p&gt;  &lt;p&gt;Certainly, you need an actual unit testing framework to start with. I would not surprise anybody by choosing JUnit test framework for my unit testing frame work. It is so widely known and used that everything that I could say would be redundant. The only thing that I would like to add, although it is said by many other is that this framework is really very easy to understand and to use it. &lt;/p&gt;  &lt;p&gt;The elegance comes when &lt;a href="http://www.junit.org/index.htm"&gt;JUnit&lt;/a&gt; is integrated with Ant. This is the first step of achieving continuous integration. Actually, the fundamental benefit of continuous integration is that it removes situations where we are looking for bugs which could not be found during unit testing but would show up when we integrate the different parts in one whole system. These bugs are some of the hardest ones to find and only continuous integration testing could save us from a lot of headache in later phases of a project development. The integration of JUnit with Ant does exactly that.&lt;/p&gt;  &lt;p&gt;Furthermore, because my project is a server-side application, I needed some framework for unit testing server-side code. I choose &lt;a href="http://jakarta.apache.org/cactus/" style="color: blue; text-decoration: underline;"&gt; Cactus&lt;/a&gt; because it uses JUnit and could be integrated with Ant. The intent of Cactus is to lower the cost of writing tests for server-side code .Cactus implements an in-container strategy. I haven’t work with other testing frameworks for server-side code, but this was the framework that I had the most problems with from all other that I had used in my project until now. There were moments when I was very close to give up on it. I had so many problems only with configuring HSql database on JBoss server, but once I figured it out, I was wondering what took me so long. This wasn’t the case with Cactus framework. After been stacked with it for a long time, finally I succeed to make it work on both Tomcat and JBoss servers. Actually, most of the problems were on JBoss, but Tomcat wasn’t easy either. However, I am hoping for not having any problems with Cactus framework because I have no idea how I made it work. I am taking “once you made it work, just don’t touch anything anymore” approach with Cactus.&lt;/p&gt;  &lt;p&gt;One of the problems was that there wasn’t implemented property in “cactus” task for JBoss.4.0.0 yet, so that I had to use the more complicated “runservertest” task. When this task is being used, it should be provided tasks for stopping and starting the current server. &lt;/p&gt;  &lt;p&gt;However, I was very satisfied at the end. Although, Cactus framework was very difficult for me to configure and make it run, I found two very important bugs with Cactus testing that I would have very, very hard time finding. One of them was a bug that I had made. It was related to setup test data in the database. I had exchanged the roles for administrator and regular user. The strange thing was that when I tested via a web browser, everything worked fine, but Cactus find this data inconsistency. Otherwise, it would have shown up much later in the development of the project and would have created a lot of troubles for me. Just the thought about how much time I was going to spend on debugging for some minor bug like this, made me appreciate in-container unit testing as well as the continuous integration testing. &lt;/p&gt;  &lt;p&gt;The second bug wasn’t mine! While cactus tests worked perfectly well on Tomcat server, they didn’t work on JBoss.4.0.0. It was very strange. The problem was in the statement:&lt;/p&gt;  &lt;p&gt;&lt;span style="color:blue;"&gt;request.isUserInRole(“user”);&lt;/span&gt;&lt;/p&gt;  &lt;p&gt;JBoss.4.0.0 always returned false. After a lot of debugging and with the argument that this works on Tomcat, I started wondering about JBoss handling of “request.isUserInRole()”. I started searching the web and surprise, JBoss.4.0.0, which was released in this September (2004) has a bug and the statement above always returns false. Fortunately for me, somebody else found this bug, described in &lt;a href="http://www.jboss.org/index.html?module=bb&amp;op=viewtopic&amp;amp;p=3849176#3849176"&gt; this post &lt;/a&gt;one week before me. There has been a patch released for this bug  that could be found &lt;a href="http://www.jboss.org/index.html?module=bb&amp;op=viewtopic&amp;amp;t=54470"&gt;here&lt;/a&gt;. &lt;/p&gt;  &lt;p&gt;Finding these two bugs convinced me very strongly for the need of in-container unit testing combined with continuous integration testing and for Test Driven Development as a whole. I will try to apply this kind of development very consciously and strictly in this as well as any future projects.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-111362148451945121?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2005/04/test-driven-development-tdd.html' title='Continuous Integration'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/111362148451945121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=111362148451945121&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111362148451945121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/111362148451945121'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2005/04/continuous-integration.html' title='Continuous Integration'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-109846479271657236</id><published>2004-09-18T13:05:00.001-05:00</published><updated>2005-10-18T23:55:36.790-05:00</updated><title type='text'>Page Layout</title><content type='html'>&lt;b&gt;Using SiteMesh versus Struts Tiles&lt;/b&gt;&lt;br /&gt;&lt;p class="MsoNormal" style="text-align: left;" align="center"&gt;by Igor Stoyanov&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p class="MsoNormal"&gt;I needed web-application integration system to aid in creating the many pages of the web site for which a consistent look/feel, navigation, and layout scheme is required. Such frameworks are Struts Tiles and &lt;a href="http://www.opensymphony.com/sitemesh/" style="color: blue; text-decoration: underline;"&gt; SiteMesh&lt;/a&gt;. While Struts Tiles are wide spread used and known, SiteMesh is an open source web-page layout and decoration framework and web- application integration framework, which is very powerful but not so popular.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; Although, I still have some thought about my decision not to use portlets (at least for now), I am more than sure that choosing SiteMesh rather than Struts Tiles is not the right but the only decision than someone who has worked with both technologies could choose. The reasons are more than many but there are some that were very decisive. Some of the main reason is that SiteMesh is much easier to configure and use (less typing and easier to understand). Using Tiles, you need to have your forwards go to a "tiles page" versus the direct JSP. SiteMesh takes the approach that your page (your JSP) doesn't even know or care that it's being decorated. Using Tiles, each individual page you want to go to has to be associated with a layout - Major pain! Every time you create a new JSP that you want to forward to, you have to create another tiles definition and associate it with a layout and forward to the Tile page (versus the JSP). &lt;/p&gt;  &lt;p class="MsoNormal"&gt;The problem with most of the available frameworks for solving this type of business requirement like Struts Tiles is that they are either platform- or framework-specific. When you're using Tiles for decoration, you have to create tiles definition in &lt;em&gt;tiels-defs.xml&lt;/em&gt;. Inside of your &lt;em&gt;struts-config.xml&lt;/em&gt; while declaring forwards, you will have to use these  tiles' definition instead of actual JSP.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; The easiest possible solution is to let each of your web applications create plain HTML content without knowing about how it is being decorated, and only then have something else choose and apply appropriate decorators. This is precisely what SiteMesh does.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; Although, SiteMesh is ideal for use with J2EE applications, however it can be integrated with server-side web architectures that are not Java based such as CGI (Perl/Python/C/C++/etc), PHP, Cold Fusion, .NET etc...&lt;/p&gt;  &lt;p class="MsoNormal"&gt; SiteMesh intercepts requests to any static or dynamically generated HTML page requested through the web-server, parses the page, obtains properties and data from the content and generates an appropriate final page with modifications to the original. This is based upon the well-known &lt;i&gt; &lt;a href="http://c2.com/cgi/wiki?GangOfFour" style="color: blue; text-decoration: underline;"&gt; GangOfFour&lt;/a&gt; Decorator&lt;/i&gt; design pattern.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; SiteMesh  can also include entire HTML pages as a &lt;b&gt;Panel&lt;/b&gt; within another page. This is similar to a Server-Side Include, except that the HTML document will be modified to create a visual window (using the document's &lt;b&gt;Meta-data&lt;/b&gt; as an  aid) within a page. Using this feature, &lt;i&gt;Portal&lt;/i&gt; type web sites can be  built very quickly and effectively. This is based upon the well-known &lt;i&gt; &lt;a href="http://c2.com/cgi/wiki?GangOfFour" style="color: blue; text-decoration: underline;"&gt; GangOfFour&lt;/a&gt; Composite&lt;/i&gt; design pattern.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; My experience with SiteMesh was incredibly positive and I would not look for any alternative framework anytime soon. The installation and the set up of SiteMesh includes:.&lt;/p&gt;  &lt;p&gt; &lt;span style="font-family:Symbol;"&gt;·&lt;/span&gt; SiteMesh is based on Java, J2EE, and XML and depends on filters, a very useful feature introduced in the Servlet specification 2.3, so we have to inform our web application about the SiteMesh filter. Adding the following lines to &lt;i&gt;web.xml&lt;/i&gt; can do this:&lt;/p&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;filter&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt; &amp;lt;filter-name&amp;gt;sitemesh&amp;lt;/filter-name&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;filter-class&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;      com.opensymphony.module.sitemesh.filter.PageFilter&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;/filter-class&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/filter&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;filter-mapping&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt; &amp;lt;filter-name&amp;gt;sitemesh&amp;lt;/filter-name&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/filter-mapping&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;p&gt;Here we are telling the container that all requests to this web application&lt;br /&gt;should go through PageFilter&lt;code  style="font-family:Courier New;"&gt;&lt;/code&gt;. The PageFilter class is part of &lt;em&gt;sitemesh-2.1.jar&lt;/em&gt;, which you can download from the &lt;a href="http://www.opensymphony.com/sitemesh/download.html" style="color: blue; text-decoration: underline;"&gt;SiteMesh downloads page&lt;/a&gt;. Once downloaded, you should copy &lt;i&gt;&lt;br /&gt;sitemesh-2.1.jar&lt;/i&gt; to the &lt;em&gt;/WEB-INF/lib&lt;/em&gt; folder.&lt;/p&gt;&lt;span style="font-family:Symbol;"&gt;·&lt;/span&gt;  Create a &lt;em&gt;decorators.xml&lt;/em&gt; file in the &lt;em&gt;WEB-INF&lt;/em&gt; folder like this:&lt;br /&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:green;"&gt;&amp;lt;!—- declare the directory that our decorators will be &lt;/span&gt;&lt;span style="font-family:wingdings,mon;"&gt;&lt;/span&gt;&lt;/code&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:green;"&gt;--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;decorators defaultdir="/decorators"&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!—- decorate all page in our web application with “default.jsp” decorator (Decorator Pattern)--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;decorator name="default" page="default.jsp"&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;          &amp;lt;pattern&amp;gt;/*&amp;lt;/pattern&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;/decorator&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!—- include a panels in the main window. Create visual windows in a page (Composite Pattern)--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;decorator name="box" page="box.jsp"/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/decorators&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;em&gt;decorators.xml&lt;/em&gt; file is used to define decorators for your appli&lt;span style="font-size:100%;"&gt;cation. In this file,  each  &amp;lt; decorator&amp;gt;&lt;code  style="font-family:Courier New;"&gt;&lt;/code&gt; element defines one decorator. The name&lt;code  style="font-family:Courier New;"&gt;&lt;/code&gt; attribute is used to define a n&lt;/span&gt;ame for that decorator, while the page&lt;code  style="font-family:Courier New;"&gt;&lt;/code&gt; attribute defines the JSP page that should be used for decorating. The &amp;lt;pattern&amp;gt;&lt;code  style="font-family:Courier New;"&gt;&lt;/code&gt; child element defines when a particular decorator should be applied.&lt;br /&gt;&lt;p&gt;The last thing to do in order for SiteMesh to work is to create the decorators. The most important elements in a decorator are: &lt;/p&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;?xml version="1.0"?&amp;gt; &lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;&amp;lt;jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    xmlns:c="http://java.sun.com/jstl/core_rt" &lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    xmlns:fmt="http://java.sun.com/jstl/fmt_rt"&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    xmlns:decorator="http://www.opensymphony.com/sitemesh/decorator" &lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    xmlns:page="http://www.opensymphony.com/sitemesh/page" &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    version="1.2"&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;    &amp;lt;jsp:directive.page session="false" language="java" errorPage="/error.jsp" pageEncoding="UTF-8" contentType="text/html; charset=utf-8"/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;html  xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;   &amp;lt;head&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;     &amp;lt;title&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;        &amp;lt;fmt:message key="webapp.prefix"/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;        &amp;lt;decorator:title default="Structure"/&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;     &amp;lt;/title&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;     &amp;lt;decorator:head /&amp;gt;    &lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code  style="font-family:Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;/head&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code style="font-family: Courier New;"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;body&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code style="font-family: Courier New;"&gt;&lt;span style="color:blue;"&gt;    &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!-- Some decorations here( header, page layout and so on)--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code style="font-family: Courier New;"&gt;&lt;span style="color:green;"&gt;            .......................&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code style="font-family: Courier New;"&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code style="font-family: Courier New;"&gt;&lt;span style="color:green;"&gt;        &amp;lt;!-- includes decorated page --&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code face="Courier New"&gt;&lt;span style="color:blue;"&gt;        &amp;lt;decorator:body /&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code face="Courier New"&gt;&lt;/code&gt;&lt;code face="Courier New"&gt;&lt;/code&gt;&lt;code face="Courier New"&gt;&lt;span style="color:blue;"&gt;     &lt;/span&gt;&lt;span style="color:green;"&gt;&amp;lt;!-- More decorations here( footer, copyrights and so on.)--&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code face="Courier New"&gt;&lt;span style="color:blue;"&gt;        .......................&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;code face="Courier New"&gt;&lt;span style="color:blue;"&gt;  &amp;lt;/body&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;pre   style="margin: 0in 0in 0.0001pt;font-family:Courier New;font-size:10pt;"&gt;&lt;code face="Courier New"&gt;&lt;span style="color:blue;"&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;span style="font-family:georgia,serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;Of course, this is just the basic but I think that even this could show&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;how easy, straightforward and in the same time very powerful is the&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;SiteMesh framework. I implemented everything that I wanted very easily&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;for my web interface without any compromises. I just wish that all&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;tools and frameworks that I use are so simple, easy to use and&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:arial;" &gt;intuitive like SiteMesh.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-109846479271657236?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2004/09/page-layout.html' title='Page Layout'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/109846479271657236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=109846479271657236&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/109846479271657236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/109846479271657236'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2004/09/page-layout.html' title='Page Layout'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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><id>tag:blogger.com,1999:blog-6178209.post-109846456714267519</id><published>2004-09-15T13:01:00.000-05:00</published><updated>2005-09-11T13:50:32.410-05:00</updated><title type='text'>Web Interface</title><content type='html'>&lt;b&gt;&lt;br /&gt;Discussing the implementation of a user web based  interface using JavaScript, CSS or Java Portlets.&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;by Igor Stoyanov&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(255, 0, 0);"&gt;Note: This blog entry was before AJAX era. It sounds funny reading it today, but I would say it was kind of advance at the time when using javascript was considered evil.&lt;/span&gt;&lt;br /&gt;  &lt;p class="MsoNormal"&gt;Properly done web page design could be very important for the success of a given web application project. There were a couple of alternatives here which includes different compromises between portability, user satisfaction as well as performance issues. One possible way of implementing user web interface was using a new java specification for building web portals, called portlets. After very basic examination of this technology I decided not to use it for a couple of reason:&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: -0.25in; margin-left: 0.5in;"&gt;1)&lt;span style=""&gt;      &lt;/span&gt;A request to the server is post every time a user wants to minimize, maximize or do something with the appearance of a particular portlet. This makes the overall performance of the web site to appear not very satisfactory. As an example I could give the new Loyola web based system – LOCUS. I don’t know if the provider, PeopleSoft, had used portlets but the site responding in such a way. Even for very simple operation as expanding of a tree structured menu, which doesn’t need any processing by the server, a request to the server is made and the whole page should be loaded again. This makes their web site looks very slow and a user experience is not very satisfactory, especially if the user uses dial up internet access. Since, I want a user to fill the web site very alive and responsive this was a major issue against using portlets. However, I suspect that later in the project I could encounter some transactional and other issues related to a web portal to be achieved in not so elegant way as if I decided on using portlets on first place. I have to come back to this particular choice later in the project in order more fully to estimate the benefits of using or not using portlets as web interface framework.&lt;/p&gt;  &lt;p class="MsoNormal" style="text-indent: -0.25in; margin-left: 0.5in;"&gt;2)&lt;span style=""&gt;      &lt;/span&gt;Another side of using portlet is that as a new technology, there are many different implementations and portable issues related with that.&lt;/p&gt;  &lt;p class="MsoNormal"&gt;Because of all stated above, I decided on using CSS and JavaScript as primary user interface technology. Although JavaScript and CSS are not very portable among different browsers and some of the users could disable JavaScript, I decided on using them only for web interface operation related to the feel and look of a web page. This would make the web site look more responsive for the users and overall more users would be satisfied than having problems with the web site.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; In the process of implementing the web interface, I succeed in achieving my goals about the look and feel of the web interface. I believe that working with JavaScript together with CSS was sati factorable for me and the combination of these two technologies could enable you with the ability to implement very powerful features for your web site interface. &lt;/p&gt;  &lt;p class="MsoNormal"&gt; I used JavaScript and CSS for minimizing, maximizing and deleting of a different box window. Also, the state of the page layout and the different box windows are stored as cookies, so that every time a user go to the web site, he/she we see the same page layout that he/she left before closing of the web browser.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; However, I didn’t implement with JavaScript any essential function concerning processing any user information. Even if JavaScript is disabled, a user would be able to use all major functions of the web site; just the experience of using this web application would be a little less satisfactory.&lt;/p&gt;  &lt;p class="MsoNormal"&gt; As a conclusion, I would like to say that looking at other  very popular web portals like &lt;a href="http://my.yahoo.com/" style="color: blue; text-decoration: underline;"&gt; http://my.yahoo.com&lt;/a&gt;  and &lt;a href="http://january.rr.com/flash/" style="color: blue; text-decoration: underline;"&gt; Road Runner&lt;/a&gt; using JavaScript, CSS and other not so portable technologies like Java applet, Macromedia and so on are very heavily presented in order to make user interaction very fulfilling. Thus, I believe that I made a good choice with JavaScript but I will see how it would integrate with Java Server Faces in the later phases of the project.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6178209-109846456714267519?l=blog.igorstoyanov.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://igorstoyanov.blogspot.com/2004/09/web-interface.html' title='Web Interface'/><link rel='replies' type='application/atom+xml' href='http://blog.igorstoyanov.com/feeds/109846456714267519/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6178209&amp;postID=109846456714267519&amp;isPopup=true' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/109846456714267519'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6178209/posts/default/109846456714267519'/><link rel='alternate' type='text/html' href='http://blog.igorstoyanov.com/2004/09/web-interface.html' title='Web Interface'/><author><name>Igor</name><uri>http://www.blogger.com/profile/12832903167357753682</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></feed>
