<?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'><id>tag:blogger.com,1999:blog-37267515</id><updated>2009-10-08T23:53:52.859-03:00</updated><title type='text'>Thoroughly Applied Logic</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>14</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-37267515.post-657326075253307332</id><published>2008-07-24T21:37:00.007-03:00</published><updated>2008-07-24T22:18:25.189-03:00</updated><title type='text'>Links for July 24, 2008</title><content type='html'>&lt;p&gt;One of the best arguments for REST is in this &lt;a href="http://research.sun.com/techrep/1994/abstract-29.html"&gt;paper&lt;/a&gt; from 1994.&lt;br /&gt;Ruby: &lt;a href="http://blog.jayfields.com/2008/07/ruby-underuse-of-modules.html"&gt;Modules&lt;/a&gt; over meta-classes and opened classes.&lt;br /&gt;&lt;a href="http://www.slideshare.net/rabble/beyond-rest-building-data-services-with-xmpp-pubsub?src=embed"&gt;Slides&lt;/a&gt; for "Beyond REST? Building Data Services with XMPP PubSub" OSCON &lt;a href="http://en.oreilly.com/oscon2008/public/schedule/detail/4359"&gt;session&lt;/a&gt;.&lt;br /&gt;Metaprogramming &lt;a href="http://www.infoq.com/news/2008/07/metaprogramming-roundup"&gt;roundup&lt;/a&gt; on InfoQ.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-657326075253307332?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/657326075253307332/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=657326075253307332' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/657326075253307332'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/657326075253307332'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/07/links-for-july-24-2008.html' title='Links for July 24, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-5106414282094433825</id><published>2008-06-29T17:30:00.002-03:00</published><updated>2008-06-29T17:34:20.553-03:00</updated><title type='text'>Links for June 29, 2008</title><content type='html'>Agility and|vs. organization &lt;a href="http://blog.toolshed.com/2008/06/stage-0-not-rea.html"&gt;culture&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-5106414282094433825?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/5106414282094433825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=5106414282094433825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/5106414282094433825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/5106414282094433825'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-29-2008.html' title='Links for June 29, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-248309599961711211</id><published>2008-06-25T11:46:00.003-03:00</published><updated>2008-06-25T11:57:10.988-03:00</updated><title type='text'>Links for June 25, 2008</title><content type='html'>Why TDD (and various other techniques) &lt;a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2008/06/the-flawed-theo.html"&gt;work&lt;/a&gt;.&lt;br /&gt;Uncle Bob on one of the ingredients of a &lt;a href="http://blog.objectmentor.com/articles/2008/06/24/so-you-want-your-code-to-be-maintainable"&gt;flexible system design&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-248309599961711211?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/248309599961711211/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=248309599961711211' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/248309599961711211'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/248309599961711211'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-25-2008.html' title='Links for June 25, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-2536404289287409948</id><published>2008-06-24T09:53:00.002-03:00</published><updated>2008-06-24T09:57:24.987-03:00</updated><title type='text'>Links for June 24, 2008</title><content type='html'>&lt;a href="http://www.malhar.net/sriram/kilim/"&gt;Kilim&lt;/a&gt; is a message-passing framework for Java that provides ultra-lightweight threads and facilities for fast, safe, zero-copy messaging between these threads.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-2536404289287409948?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/2536404289287409948/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=2536404289287409948' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/2536404289287409948'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/2536404289287409948'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-24-2008.html' title='Links for June 24, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-1645077328813025236</id><published>2008-06-23T09:59:00.004-03:00</published><updated>2008-06-23T14:24:42.194-03:00</updated><title type='text'>Links for June 23, 2008</title><content type='html'>&lt;p&gt;&lt;br /&gt;&lt;a href="http://dev.zeraweb.com/introducing-functor/"&gt;Method overloading using pattern-matching in Ruby&lt;/a&gt;&lt;br /&gt;&lt;a href="http://citeseer.ist.psu.edu/cache/papers/cs/32018/http:zSzzSzwww.jilp.orgzSzvol5zSzv5paper12.pdf/ertl03structure.pdf"&gt;The Structure and Performance of Efficient Interpreters&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.sagecertification.org/events/vee05/full_papers/p153-yunhe.pdf"&gt;Stack Versus Registers Virtual Machines&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.tecgraf.puc-rio.br/~lhf/ftp/doc/jucs05.pdf"&gt;The Implementation of Lua 5.0&lt;/a&gt;&lt;br /&gt;&lt;a href="http://weblog.raganwald.com/2008/06/macros-hygiene-and-call-by-name-in-ruby.html"&gt;Raganwald's rewrite gem with explanations&lt;/a&gt;&lt;br /&gt;And some links from the above post:&lt;br /&gt;&lt;a href="http://www.bookshelf.jp/texi/onlisp/onlisp_10.html"&gt;Variable capture in Lisp&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Hygienic_macro"&gt;Hygienic macros&lt;/a&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Thunk#Thunk_as_delayed_computation"&gt;Thunks as a delayed computations&lt;/a&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/37267515-1645077328813025236?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/1645077328813025236/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=1645077328813025236' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/1645077328813025236'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/1645077328813025236'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-23-2008.html' title='Links for June 23, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-1528633681603520435</id><published>2008-06-20T10:23:00.001-03:00</published><updated>2008-06-20T10:25:18.236-03:00</updated><title type='text'>Links for June 20, 2008</title><content type='html'>&lt;p&gt;&lt;a href="http://www.randomhacks.net/articles/2002/09/13/hygienic-macros"&gt;Why Hygienic Macros Rock&lt;/a&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/37267515-1528633681603520435?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/1528633681603520435/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=1528633681603520435' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/1528633681603520435'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/1528633681603520435'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-20-2008.html' title='Links for June 20, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-857943092727379882</id><published>2008-06-18T11:26:00.005-03:00</published><updated>2008-06-18T11:40:22.370-03:00</updated><title type='text'>Links for June 18, 2008</title><content type='html'>&lt;p&gt;&lt;a href="http://weblog.raganwald.com/2008/06/not-going-dark.html"&gt;Lisp macros functionality in Ruby&lt;/a&gt;&lt;br /&gt;&lt;a href="http://weblog.raganwald.com/2008/05/lets-organize-our-ruby-code.html"&gt;Variable scope limiting in Ruby&lt;/a&gt;&lt;br /&gt;&lt;a href="http://peripateticaxiom.blogspot.com/2008/06/tdd-mocks-and-design.html"&gt;TDD, Mocks and Design&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-857943092727379882?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/857943092727379882/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=857943092727379882' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/857943092727379882'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/857943092727379882'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2008/06/links-for-june-18-2008.html' title='Links for June 18, 2008'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-8722200121447605967</id><published>2007-02-20T13:40:00.000-04:00</published><updated>2007-02-20T13:44:40.239-04:00</updated><title type='text'>Code Smells Taxonomy</title><content type='html'>A short taxonomy of code smells &lt;a href="http://www.soberit.hut.fi/mmantyla/BadCodeSmellsTaxonomy.htm"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-8722200121447605967?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/8722200121447605967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=8722200121447605967' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/8722200121447605967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/8722200121447605967'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2007/02/code-smells-taxonomy.html' title='Code Smells Taxonomy'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-835016815884865563</id><published>2007-02-20T09:50:00.000-04:00</published><updated>2007-02-20T09:53:39.681-04:00</updated><title type='text'>TDD Anti-patterns</title><content type='html'>James Carr has a &lt;a href="http://blog.james-carr.org/?p=44"&gt;post&lt;/a&gt; on tdd anti-patterns in his blog. I'm sure you will recognise a few.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-835016815884865563?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/835016815884865563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=835016815884865563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/835016815884865563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/835016815884865563'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2007/02/tdd-anti-patterns.html' title='TDD Anti-patterns'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-7428804602970928853</id><published>2007-02-19T23:24:00.000-04:00</published><updated>2007-02-19T23:38:35.688-04:00</updated><title type='text'>Software Quality from Systems Thinking Perspective</title><content type='html'>Lately I was in several conversations about software quality, trust and office politics. It seems that the standard argument is that we should strive to write quality software, but in the real world we have to make compromises. Moreover, we (as developers) cannot assume the responsibility for technical decisions when there are higher interests at stake.&lt;br /&gt;&lt;br /&gt;I don't want to repeat what Ryan &lt;a href="http://on-agile.blogspot.com/2006/11/let-experts-make-decisions.html"&gt;said&lt;/a&gt; before. Instead, I wanted to look at the problem from a systems thinking perspective.&lt;br /&gt;&lt;br /&gt;Code base with a low amount of &lt;a href="http://www.martinfowler.com/bliki/TechnicalDebt.html"&gt;technical debt&lt;/a&gt; is a healthy code base. It seldom happens that it's worth acquiring technical debt. It's very hard to estimate the amount of effort required to remove it, making it an incalculable risk, an uncertainty in the code base. For a longer discussion see Martin Fowler's post on technical debt.&lt;br /&gt;&lt;br /&gt;A healthy code base allows developers working with it to provide reliable estimates about the amount of effort required to implement a feature. Also, a lesser number of unknowns in the code base gives developers ability to work at a predictable pace while maintaining quality. Better estimates and a stable rate of  progress means developers are more likely to complete the stories they committed themselves to for a given iteration.&lt;br /&gt;&lt;br /&gt;Keeping promises is a good way to gain trust; completing tasks that developers promised to deliver builds up trust with the product owner/customer team (and possibly within other parts of the company).  When a product owner has a high degree of trust in the development team, she is more comfortable with leaving technical decisions in the hands of developers. This completes the circle: since developers are entrusted with the making of technical decisions, they can maintain healthy code that is high in quality.&lt;br /&gt;&lt;br /&gt;In systems thinking this pattern is known as "Reinforcing Loop". The above example shows the loop that improves code quality and builds up trust in developers over time. Such a loop can also amplify negative changes.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_heKjn1oc924/Rdpqj_DCsfI/AAAAAAAAAAM/SjFeE6sjW1U/s1600-h/quality_reinforcing_feedback.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_heKjn1oc924/Rdpqj_DCsfI/AAAAAAAAAAM/SjFeE6sjW1U/s400/quality_reinforcing_feedback.png" alt="" id="BLOGGER_PHOTO_ID_5033452699992109554" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In the presence of technical debt in the code base it's hard (if not impossible) for a developer to provide a reliable estimate. For the same reason a predictable rate of progress is hard to achieve - the amount of actual work is unknown. Depending on the size of the technical debt developers are likely to find it hard to deliver on their commitments. In such a situation developers will be under pressure from other developers on the team (and oftentimes the developer herself) and from the product owner (and possibly other parts of the organization) to make shortcuts (or in other words to increase the technical debt).  Lack of trust in developers, and uncertainty in the amount of work required to improve quality and health of code base, will make a product owner hesitant to allocate time in the iteration for such work.&lt;br /&gt;&lt;br /&gt;There is a concept of leverage in systems thinking - a sometimes small, well focused action that can produce significant, enduring improvements. Code health provides leverage that developers can use to bring improvements into software development process. By maintaining code health at a high level we (developers) create work conditions where developers are trusted and can continue to improve code health. By sacrificing quality we get trapped into a vicious cycle of eroding code health and vanishing trust.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-7428804602970928853?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/7428804602970928853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=7428804602970928853' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/7428804602970928853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/7428804602970928853'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2007/02/software-quality-from-systems-thinking.html' title='Software Quality from Systems Thinking Perspective'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_heKjn1oc924/Rdpqj_DCsfI/AAAAAAAAAAM/SjFeE6sjW1U/s72-c/quality_reinforcing_feedback.png' height='72' width='72'/><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-8929796554101061180</id><published>2007-01-30T09:06:00.000-04:00</published><updated>2007-01-30T09:45:43.219-04:00</updated><title type='text'>Double-checked locking doesn't work in Java</title><content type='html'>This doesn't work in Java:&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;class Foo {&lt;br /&gt; private Helper helper = null;&lt;br /&gt;&lt;br /&gt; public Helper getHelper() {&lt;br /&gt;  if (helper == null)&lt;br /&gt;    synchronized(this) {&lt;br /&gt;      if (helper == null)&lt;br /&gt;        helper = new Helper();&lt;br /&gt;    }&lt;br /&gt;  return helper;&lt;br /&gt; }&lt;br /&gt;}&lt;/pre&gt;It is possible that to due to compiler-based reorderings &lt;span style="font-family:monospace;"&gt;helper&lt;/span&gt; reference will be initialised while the fields in &lt;span style="font-family:monospace;"&gt;Helper&lt;/span&gt; object will be at their default values. There are other more subtle problems with the double-checked locking approach. You can read the complete paper &lt;a href="http://www.cs.umd.edu/%7Epugh/java/memoryModel/DoubleCheckedLocking.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In most cases such an optimisation is not worth the trouble. If you want to lazy-initialise a singleton, define it as a static field in another class:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;class Helper {&lt;br /&gt; class HelperSingleton {&lt;br /&gt;   static Helper singleton = new Helper();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public Helper getHelper() {&lt;br /&gt;   return HelperSingleton.singleton;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;The semantics of Java guarantees that &lt;span style="font-family:monospace;"&gt;singleton&lt;/span&gt; field is going to be initialised only when referenced, and that all threads accessing the field will see the writes performed during the initialisation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-8929796554101061180?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/8929796554101061180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=8929796554101061180' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/8929796554101061180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/8929796554101061180'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2007/01/double-checked-locking-doesnt-work-in.html' title='Double-checked locking doesn&apos;t work in Java'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-2216100377595344593</id><published>2007-01-29T17:58:00.000-04:00</published><updated>2007-01-29T18:05:56.086-04:00</updated><title type='text'>Keeping tests useful</title><content type='html'>There is a subtle difference between writing production code and test code. Both have to be intention-revealing and maintainable, but good tests are also specifications. As such, tests have to be crystal clear about what's being tested and show the usage of api/code being tested.&lt;br /&gt;&lt;br /&gt;Quite a few times, I've seen test-data, setup for mocks, and assertions being tucked (far) away from the actual test, all in the name of maintainability. Hiding these things away makes reading tests harder, and can hide problems with the production code. Imagine a situation when you have (oh, no!) a constructor with ten parameters. To make tests more maintainable, you create a 'helper' method that returns a new instance of the class, and requires only three parameters. You just saved yourself from tons of copy-paste code-reuse, right?&lt;br /&gt;&lt;br /&gt;That's certainly one way to look at the problem. However, why does the constructor need ten parameters? Could it be the case that the class has too many responsibilities? Now it's hard to tell; the tests are hiding the problem. This makes them less *useful* than they could be.&lt;br /&gt;&lt;br /&gt;Next time you're writing tests and find yourself creating shortcuts for repetitive bits of code or heavy setup, pause and say to yourself: &lt;a href="http://headrush.typepad.com/creating_passionate_users/2006/12/two_more_words_.html"&gt;"Hmmm, how interesting..."&lt;/a&gt;. Perhaps a better way to solve the problem will present itself.&lt;br /&gt;&lt;br /&gt;Thanks to &lt;a href="http://onagile.com/"&gt;Ryan Cooper "Agile Guru"&lt;/a&gt; for help with this post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-2216100377595344593?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/2216100377595344593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=2216100377595344593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/2216100377595344593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/2216100377595344593'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2007/01/keeping-tests-useful.html' title='Keeping tests useful'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-116399394932477205</id><published>2006-11-19T23:36:00.000-04:00</published><updated>2006-11-19T23:42:15.506-04:00</updated><title type='text'>Behavioral Smells</title><content type='html'>I was reading Martin Fowler's post on &lt;a href="http://martinfowler.com/bliki/PairProgrammingMisconceptions.html"&gt;pairing misconceptions&lt;/a&gt;, where at the end he writes about how problematic code base encourages problematic developer behaviour: "It's only worth pairing on complex code, rote code yields no advantage". The problem here is that rote code is a mechanical solution, created without taking into account the bigger picture - precisely the problem that pairing helps to solve. This type of problem is similar to a code smell but is expressed through human interaction (or its absense in this case) - you could call it a behavioral smell.&lt;br /&gt;&lt;br /&gt;I noticed that on the current project, in addition to somewhat reluctant pairing, the team has another problem - oftentimes when a business problem is discussed, the conversation revolves around low-level technical details. This prevent the customer team from contributing to the resolution of the problem.&lt;br /&gt;&lt;br /&gt;In our case this behaviour is caused by a weak domain model that is insufficiently isolated from legacy db schema and esb messages. The model lacks useful abstractions representing business concepts and resulting business logic is very procedural - expressed using low-level operations on objects' fields that were extracted by breaking encapsulation. In the absence of higher-level abstractions the conversation is forced into technicalities of the problem.&lt;br /&gt;&lt;br /&gt;I find it interesting how distinct code problems cause rather distinct behavioral smells. I am sure that there are more - perhaps this a topic to bring up during a retrospection meeting? By drawing attention to such behavioural smells we can identify issues before they grow into serious problems or highlight existing problems in our code bases.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-116399394932477205?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/116399394932477205/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=116399394932477205' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/116399394932477205'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/116399394932477205'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2006/11/behavioral-smells.html' title='Behavioral Smells'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-37267515.post-116286717040657740</id><published>2006-11-06T22:38:00.000-04:00</published><updated>2006-11-06T22:40:15.156-04:00</updated><title type='text'>Hello world!</title><content type='html'>&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/37267515-116286717040657740?l=appliedlogic.blogspot.com'/&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://appliedlogic.blogspot.com/feeds/116286717040657740/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=37267515&amp;postID=116286717040657740' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/116286717040657740'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/37267515/posts/default/116286717040657740'/><link rel='alternate' type='text/html' href='http://appliedlogic.blogspot.com/2006/11/hello-world.html' title='Hello world!'/><author><name>Dmitri</name><uri>http://www.blogger.com/profile/09301294710043467136</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='12056633651501762965'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry></feed>