<?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-4245061821217376141</id><updated>2011-07-08T00:25:26.055+02:00</updated><category term='scala'/><category term='java'/><category term='software engineering'/><title type='text'>WillowSense</title><subtitle type='html'>This blog is mostly about common sense, but you'll probably find something related to software development or computer science here as well.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>15</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-2173881148667070384</id><published>2010-07-21T22:16:00.005+02:00</published><updated>2010-07-21T22:38:08.923+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Go with the flow</title><content type='html'>&lt;span xmlns=""&gt; &lt;p&gt;The &lt;a href="http://www.spin.org.za/"&gt;SPIN&lt;/a&gt; meeting in Cape Town this month again impressed with a high quality presentation. Phil Barrett from &lt;a href="http://www.userexperience.co.za/"&gt;Flow&lt;/a&gt; highlighted the importance of user interaction design by elaborating on the role of the &lt;em&gt;user experience designer &lt;/em&gt;in the software development process&lt;em&gt;.&lt;/em&gt; He inspired us to think about better user interfaces, ensured us that Agile has room for UI design, and certainly made some of us wish we could have him in our team. I could not attempt even a summary of all the good things that were said. Instead I would like to share with you three key ideas that I took home from Phil's talk (obviously, these are heavily laden with my own egocentric perspectives &lt;span style="font-family:Wingdings;"&gt;J&lt;/span&gt;). &lt;/p&gt;&lt;p&gt;The first is that better user experience &lt;strong&gt;is money in your pocket.&lt;/strong&gt; It is not about being nice, doing the right thing or getting a warm and fuzzy feeling – it is about selling software or converting website visitors into website customers. It is also about beating your competitor, and keeping your customers from looking around for better solutions. In short it might be a good idea to spend some money on user interaction – even if you think your software works well. &lt;/p&gt;&lt;p&gt;The second idea is that user interaction design can easily reach a &lt;strong&gt;local maximum. &lt;/strong&gt;When you start coding you have in mind a particular solution – and as you code you become more and more tied into the many small design decisions you make along the way. Small increments are relatively inexpensive and each one improves the system ever so slightly. However, at some point change becomes difficult and your user interface could end up with a feel that is, in a very practical sense, at an optimal solution. At this juncture the identification of a better solution does not help because changing to this brave new world is simply not cost effective. You are stuck at a local maximum - it is the "payback" for all those short-cuts you took when the coding started. Avoid this situation by thinking through your user experience design carefully – and aim for that higher maximum from the start (this is very much like the concept of entropy I &lt;a href="http://willowsense.blogspot.com/2009/03/agile-is-not-fragile.html"&gt;discussed in a previous blog&lt;/a&gt;) &lt;/p&gt;&lt;p&gt;The third concept revolves around the &lt;strong&gt;role&lt;/strong&gt; &lt;strong&gt;of the user experience designer&lt;/strong&gt;. The way I see it follows purely from the pig and chicken perspective: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;If the application &lt;em&gt;does not work&lt;/em&gt;, roll your eyes (if you must) toward the developer and the tester&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the application &lt;em&gt;does the wrong thing&lt;/em&gt;, place the blame on the doorstep of the business analyst&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If the application &lt;em&gt;does the thing wrong&lt;/em&gt;, the user experience designer is your culprit &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you are not equipped or entitled to hire a user experience designer, Phil suggests that you could interview the users yourself. Focus on having an open honest conversation – ask politely, then listen carefully at the reply. Wait for four seconds before offering your comment. Good advice, I'd say!&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-2173881148667070384?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/2173881148667070384/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2010/07/go-with-flow.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/2173881148667070384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/2173881148667070384'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2010/07/go-with-flow.html' title='Go with the flow'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-6923993356099986493</id><published>2010-06-01T17:54:00.010+02:00</published><updated>2010-06-02T22:21:37.157+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Control that view to the model</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Remember that good old model, view, controller idea – simple isn't it? We need only a model, a view and a controller. Maybe we want more than one view – that would be nice. But then, what is a model – and when does one model become two models? OK, but surely the controller is simple – it must be a singleton, or not? The thing about &lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller"&gt;MVC&lt;/a&gt; is that once you get past the M, the V and the C, you may have more questions than answers. Soon we all end up with our own definition of &lt;em&gt;vanilla MVC&lt;/em&gt;. Then we deviate from this unattainable ideal. We have many excuses because we face real world problems, imperfect operating platforms, clunky programming languages, silver bullet UI frameworks and so on. &lt;/p&gt;&lt;p&gt;Maybe these realities are challenges, not excuses. Maybe throwing away the architecture is not an option and new ideals are what we need. But, before we go to that braver place, let's first find out where are we now. &lt;/p&gt;&lt;p&gt;My own vanilla perspective considers the MVC triad as three separate concerns. Each concern has a basic set of responsibilities. It goes without saying that I think this perspective is in fact crystal clear and entirely practical ;-)&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;strong&gt;Model &lt;/strong&gt;encapsulates the state, and exposes the functionality of the application. It notifies clients of significant changes to the state.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;View&lt;/strong&gt; renders the model to the end-user. It receives notifications from and performs queries on the model.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;Controller&lt;/strong&gt; defines the application behaviour. It receives a gesture event from the view, transforms this to an action and applies the action to the model. It also selects the parts of view to show as a response to an action.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;From these responsibilities, it is clear that the model is the foundation, and that it should be isolated from the view and controller. This separation is a key benefit of MVC. The idea being that one can use the same model to write diverse applications that run on different technologies. Practise show that this benefit is unlike to be a key factor in most applications. However, it does help to think along these lines when putting together your application architecture. &lt;/p&gt;&lt;p&gt;Instead of one technology independent model, I lean towards the idea that there is some part of the model that is technology specific. I separate this part into a sub-concern called the &lt;em&gt;application model&lt;/em&gt;. Those really non-technological model classes; that is the &lt;em&gt;domain model&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;This domain model exposes the functionality in terms of entities, values objects, repositories and such things. It is also responsible for validation and transactional cohesion of the information kept on long term storage. The application model is responsible for the application state - i.e. the information created during the application run cycle. This information could include session management, caching, job management, selection management and so on. &lt;/p&gt;&lt;p&gt;The application model for a web application might focus on remote user sessions, shared caching, cookie or server based user state (for shopping baskets and so on), while a rich client has client sessions, local cache and local user state in its application model. When writing for particular technology, the line between the two model types easily becomes blurred. The disadvantage of this blurring becomes very clear when the application is ported to a different technology or to a new framework. However, less radical changes could also be prohibited when mixing application and domain model classes. It could become difficult to fix non-functional problems (such as performance and responsiveness issues) without affecting key functional areas of the application.&lt;/p&gt;&lt;p&gt;The model could be a grey area, but clearly the view and the controller are technology specific. Different technologies call for different approaches on how views are to be rendered and how user gestures are captured and transformed into actions that are applied to the model. &lt;/p&gt;&lt;p&gt;It is good design practice to delineate a namespace for each concern. These namespaces form a layered design. Each namespace provides services only to those above it. At the bottom is the domain model – it does not consume services from any other namespace. Right above the domain you'll find the application model, and the view is the next layer on the stack. The top layer is the controller. The controller can use services from any other layer – and it provides no services to the other layers. &lt;/p&gt;&lt;p&gt;With these namespaces in place, the process of design starts with a decision where to place a new class, and to make sure this class does not violate the constraints imposed by its designated layer. &lt;/p&gt;&lt;p&gt;When the allocation of a class to a layer is not obvious,  consider choosing the top layer and move down only when the need arises. For instance, if it is not used by any layer other than the controller, it belongs in the controller. You can always move it down later when things become clearer – but it is more difficult to move it up to a higher level in the stack (when things become more muddy). &lt;/p&gt;&lt;p&gt;Consider yourself reminded of the MVC basics – look, think ... improve!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-6923993356099986493?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/6923993356099986493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2010/06/control-that-view-to-model.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6923993356099986493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6923993356099986493'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2010/06/control-that-view-to-model.html' title='Control that view to the model'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-6314976535219688214</id><published>2010-03-14T15:59:00.013+02:00</published><updated>2010-05-23T19:23:55.989+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Invalid ideas</title><content type='html'>Faced with a clean slate, many application architects take yet another look at &lt;a href="http://en.wikipedia.org/wiki/Model-view-controller"&gt;the model-view-controller&lt;/a&gt; (MVC) pattern to veer off the evils of a bad foundation. Even those architects that choose ready to use frameworks tend to measure these against concepts coupled with MVC. Of MVC itself many variants and interpretations exist, but I think the general idea idea is to divorce the "model" from the "view" (UI). The "controller" part is the artifact that is needed to manage the possibly complex interaction between the two. MVC regards the UI is as the presenter of information and as the initiator of many actions.&lt;br /&gt;&lt;br /&gt;In many real world applications, the idea of "present" and "initiate" is well understood and makes up a small part of the code. A lot of the code lies in the "capture" and "store" of the information. In these applications, the complexity tend to revolve around the validation rules that facilitates data capture. Vanilla MVC does not address this issue in specific detail. Sometimes it is incorrectly assumed that validation happens on the "view" side of the MVC triad.&lt;br /&gt;&lt;br /&gt;Recent developments on the &lt;a href="http://en.wikipedia.org/wiki/Domain_driven_design"&gt;domain driven design&lt;/a&gt; front also tend to suffer from this weakness. There seems to be a lack of a ubiquitous approach to validation. As you elaborate that domain model of yours you write unit test, you would conclude that many tests are about validation rules of some kind. Hence, the quality of an implemented domain model must be directly related to its ability to prevent invalid data from entering the system.&lt;br /&gt;&lt;br /&gt;"Garbage-in, garbage-out" is a mantra repeated reverently when facing a scenario where some poor sod used an application incorrectly. Bah! "Garbage-in" was the fault of the developer. Instead of blaming the sod, we should promote him to the test team!&lt;br /&gt;&lt;br /&gt;Values are supplied not only via user interfaces, but also by web services, data imports, queue processors and who knows what other ways. Consequently, field validation cannot be an issue that is simply shunted to the user interface level. Using MVC parlance: validation cannot be in the "view"; it has to be in the "model".&lt;br /&gt;&lt;br /&gt;Key to your design must be the idea that a validation rule is written once and only once. Wherever a value governed by this rule enters the domain, the rule shall be applied. Non- conformance to the rule leads ultimately to the rejection of the change.&lt;br /&gt;&lt;br /&gt;Why not simply throw an exception on the setter when an invalid value is given? The biggest problem with this approach is that the UI code (quite possibly your most important client) becomes bloated with exception handling blocks. It uses these blocks to try the translation of the cryptic exception thrown by the domain library into a meaningful error message. Mostly it fails - the message becomes irrelevant and the user is not helped. In fact he is agitated by such messages.&lt;br /&gt;&lt;br /&gt;The exception throwing plan has more problems. Some validation rules apply to a combination of values (e.g. a rule that ensures the birth date and ID number should coincide), or require other objects to be validated (e.g. the ID number must be unique). On which setter do you throw these exception?&lt;br /&gt;&lt;br /&gt;An alternative is to allow an instance of a class to be invalid at any given point in time. Such an object would have a set of validation rules that have been breached. Each rule is associated with the appropriate message text. This text is presented to the user. Keep in mind the user interface is responsible to present the error messages to the user. An exception occurs when the client tries to commit an invalid object (to storage or for further processing).&lt;br /&gt;&lt;br /&gt;Many details remain to be sussed out. The message in this blog is in the shell of a nut: Do not throw up, invalid domain objects are cool!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-6314976535219688214?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/6314976535219688214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2010/03/invalid-ideas.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6314976535219688214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6314976535219688214'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2010/03/invalid-ideas.html' title='Invalid ideas'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-5119782059815062893</id><published>2009-12-08T19:47:00.007+02:00</published><updated>2009-12-08T20:54:04.657+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Domains in context</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;A few days ago I attended a two day overview of &lt;a href="http://domaindrivendesign.org/"&gt;Domain Driven Design&lt;/a&gt; (DDD) presented by &lt;a href="http://aslamkhan.net/"&gt;Aslam Khan&lt;/a&gt;. On the surface, DDD looks like the latest wave rolling in from the timeless ocean of IT fads. Dig a little deeper and you'll find that there is nothing new to DDD. It is not a new wave, and just maybe it won't go away. To be fair, there is definitely a new buzz in the air. DDD is whispered about in many corners, not all of them dark ones. There seems to be high hopes: SOA, web-services, behaviour driven design, test driven design, Agile, Scrum – all of these good things could benefit from DDD.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;My interest in domains started long before I read the &lt;a href="http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215"&gt;DDD book&lt;/a&gt; by &lt;a href="http://blog.sym-link.com/"&gt;Eric Evans&lt;/a&gt;. I have been the driver behind a few frameworks for domain driven development efforts, and with a team that contained a few good men (and one or two woman), I have tasted the sweet successes this approach can bring. The road was not paved in gold, often I felt like a lone ranger taking it upon myself to lay bare the obvious traps of data-bound controls and other evils. Lucky for me (and for Tonto) the world is changing.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Reading the Evans book was a real pleasure. Not only did I find that it agrees with the undeniable truth, but it also had wrapped in it a few patterns I really needed. We grabbed from it some pieces to create yet another framework. Of course this one (like each of its predecessors) promised to be the best framework of all. And the promise was delivered - the time was right, the problem needed it, and the book came in very handy.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;It is fair to say the patterns in Evan's book are less vague than the Gang of Four. The book may also present the uninitiated with too many options. Place your focus on putting together the machinery that allows the development teams to roll out those precious domain classes. Keep in mind these classes must be loosely coupled and highly cohesive modules. But do not forget: on top of these classes some key user interfaces are needed; and on their sides high performance processes hammer them into shape. Do not even get me started on the mapping to the relational databases at the bottom of your architecture. Quite an interesting design challenge I assure you.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Maybe now you can understand why I was wondering how Aslam is going to chunk in years of experience and lots of ideas into a mere two day workshop. Selling DDD is difficult and implementing it for the first time is harder. Pleasant was my surprise when I noticed that he will attempt neither. Take the view that DDD is sold, and regard the implementation issues as infrastructural detail best left to others. Do this and your frame of mind is where Aslam wants it to be. &lt;/p&gt;&lt;p&gt;"Ah, but what else is there?", you may ask. The answer is obvious – it is the thing that drew all of us domain driven junkies closer to the kindle when we started on our journey. It is the absolute belief that the domain model is the key asset amongst the components of the enterprise software. It is where the knowledge lies, where the growth and refactoring happens, and also where the fun never sets.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Aslam's two day take on DDD focussed on this most important of stuffs. It is all about how to get the right model. He pulls together current topics and discusses those patterns from leading DDD books that help you come up with a good domain model from the start. Have a look at this &lt;a href="http://refcardz.dzone.com/refcardz/getting-started-domain-driven"&gt;reference card&lt;/a&gt; if you are interested in more detail of what he covered.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Consider yourself reminded: without the right model, the benefits of DDD will always be out of your reach. Thank you Aslam!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-5119782059815062893?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/5119782059815062893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/12/domains-in-context.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5119782059815062893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5119782059815062893'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/12/domains-in-context.html' title='Domains in context'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-5477678727075080517</id><published>2009-10-24T10:58:00.026+02:00</published><updated>2009-11-07T15:09:38.102+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Dual core acting in Scala</title><content type='html'>&lt;p&gt;Having a &lt;a href="http://en.wikipedia.org/wiki/Multi-core"&gt;dual core processor&lt;/a&gt; is a great thing for the operating system; but how can you make use of this cool technology as a (mere mortal) programmer? Potentially a complex issue but if you use &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; you'll be pleasantly surprised. It is the concept of &lt;span style="font-family: courier new"&gt;Actors&lt;/span&gt; and message passing that saves the day. Let me explain using an example from mathematics.     &lt;br /&gt;    &lt;br /&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/e/ea/Integration_rectangle.png"&gt;&lt;img style="margin: 0px 0px 10px 10px; width: 204px; float: right; height: 94px; cursor: hand" border="0" alt="" src="http://upload.wikimedia.org/wikipedia/commons/e/ea/Integration_rectangle.png" /&gt;&lt;/a&gt;A problem that can theoretically benefit from multiple cores is the one that calculates the integral of a function. Using the &lt;a href="http://en.wikipedia.org/wiki/Numerical_integration#Quadrature_rules_based_on_interpolating_functions"&gt;simple quadrature method &lt;/a&gt;this problem is reduced to calculating the area of all the rectangles that follow the curve, and adding these up to produce an estimate of the integral. More rectangles provide a more accurate evaluation. The image (from wikipedia) should help you get the picture.     &lt;br /&gt;Here is that algorithm coded in Scala: &lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;type R = Double&lt;br /&gt;def integrate(f : R=&amp;gt;R , a : R, b : R, intervalCount : Int ) = {  &lt;br /&gt;val intervals = (1 to intervalCount)&lt;br /&gt;val width = (b-a) / intervalCount  &lt;br /&gt;val halfW = width/2.0  &lt;br /&gt;(0.0 /: intervals) {&lt;br /&gt;  (s,i) =&amp;gt; s + width * f(a + i * width - halfW)&lt;br /&gt;}}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;Note that I created a type alias for Double called R. An interesting piece of code here is the last line of the function. The &lt;span style="font-family: courier new"&gt;/:&lt;/span&gt; operator is the &lt;span id="SPELLING_ERROR_8" class="blsp-spelling-error"&gt;foldleft&lt;/span&gt; operator. This &lt;span id="SPELLING_ERROR_9" class="blsp-spelling-error"&gt;foldleft&lt;/span&gt; starts with a value of 0.0 and calculates the sum of &lt;span style="font-family: courier new"&gt;width * f(a + i * width - &lt;span id="SPELLING_ERROR_10" class="blsp-spelling-error"&gt;halfW&lt;/span&gt;)&lt;/span&gt; for each i in intervals. &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;To calculate the integral of the Sine function from 0 to 90 degrees using 100 rectangles , the &lt;span id="SPELLING_ERROR_11" class="blsp-spelling-error"&gt;Scala&lt;/span&gt; function call looks like this: &lt;br /&gt;&lt;div&gt;&lt;br /&gt;  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;integrate(Math.sin,0,Math.toRadians(90),100)&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;Note that I pass the Java sine function as an argument. The answer is 1.0000102809119051 Increasing the number of rectangles to 10000 gives a better estimate: 1.0000000010280816. &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;Here's how I can use my dual core CPU to calculate the integral faster: divide the calculation into two smaller calculations and get each core to calculate the result of a smaller part; then add up the two results and voila I am done. The two parts are defined by using the midpoint between a and b and allowing one core work on the rectangles less than this midpoint while the other core chows the rectangles that are greater than the midpoint . Thus, if I want 10 000 rectangles, each core would do 5000 calculations. &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;Here's the divide and conquer algorithm in Scala: &lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;&lt;br /&gt;  &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;val m = (b - a) / 2.0&lt;br /&gt;val caller = scala.actors.Actor.self&lt;br /&gt;val iH = intervals / 2&lt;br /&gt;scala.actors.Actor.actor{caller!integrate(f,a,m,iH)}&lt;br /&gt;scala.actors.Actor.actor{caller!integrate(f,m,b,iH)}&lt;br /&gt;val p1 = scala.actors.Actor.receive {&lt;span style="color: #0000ff"&gt;case&lt;/span&gt; a : R =&amp;gt; a}&lt;br /&gt;val p2 = scala.actors.Actor.receive {&lt;span style="color: #0000ff"&gt;case&lt;/span&gt; a : R =&amp;gt; a}&lt;br /&gt;p1 + p2&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;The first thing to note is that there is an implicit actor called self. The ! operator combined with the actor method sends a message to the actors queue and processes it asynchronously. When these processes complete they send the result back to the caller. The caller (i.e. self) receives these messages and assigned the values p1 and p2 to the messages. &lt;br /&gt;  &lt;br /&gt;The full program is given below. I optimised the final code a bit to use a tail recursive function instead of a range. &lt;br /&gt;&lt;br /&gt;  &lt;br /&gt;I am sure you get the picture. Scala actors are real stars! &lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border-bottom: #999999 1px dashed; border-left: #999999 1px dashed; padding-bottom: 5px; line-height: 14px; background-color: #eee; padding-left: 5px; width: 96.88%; padding-right: 5px; font-family: andale mono, lucida console, monaco, fixed, monospace; height: 502px; color: #000000; font-size: 12px; overflow: auto; border-top: #999999 1px dashed; border-right: #999999 1px dashed; padding-top: 5px"&gt;&lt;code&gt;package scalablogs&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;object Application {&lt;br /&gt;&lt;br /&gt;  type R = Double&lt;br /&gt;&lt;br /&gt;  val intervals = 10000000&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def integrate(f : R=&amp;gt;R ,  a : R,  b : R, intervalCount : Int )  = {&lt;br /&gt;&lt;br /&gt;    val width = (b-a) / intervalCount&lt;br /&gt;&lt;br /&gt;    val halfW = width/2.0&lt;br /&gt;&lt;br /&gt;    def calc(i : Int, t : R) : R = {&lt;br /&gt;&lt;br /&gt;      val area = width * f(a + (i+1) * width - halfW)&lt;br /&gt;&lt;br /&gt;      if ( i &amp;lt; 2)&lt;br /&gt;&lt;br /&gt;         t + area&lt;br /&gt;&lt;br /&gt;      else&lt;br /&gt;&lt;br /&gt;         calc(i-1,t+area)&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    val r = calc(intervalCount-1,0)&lt;br /&gt;&lt;br /&gt;    r&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def integrateNormal(f : R=&amp;gt;R ,  a : R,  b : R)  = {&lt;br /&gt;&lt;br /&gt;    integrate(f,a,b,intervals)&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def integrateConcurrent(f : R=&amp;gt;R ,  a : R,  b : R ) = {&lt;br /&gt;&lt;br /&gt;    val m = (b - a) / 2.0&lt;br /&gt;&lt;br /&gt;    val caller = scala.actors.Actor.self&lt;br /&gt;&lt;br /&gt;    val iH = intervals / 2&lt;br /&gt;&lt;br /&gt;    scala.actors.Actor.actor{caller!integrate(f,a,m,iH)}&lt;br /&gt;   scala.actors.Actor.actor{caller!integrate(f,m,b,iH)}&lt;br /&gt;&lt;br /&gt;    val p1 = scala.actors.Actor.receive {case a : R =&amp;gt; a}&lt;br /&gt;&lt;br /&gt;    val p2 = scala.actors.Actor.receive {case a : R =&amp;gt; a}&lt;br /&gt;&lt;br /&gt;    p1 + p2&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  def main(args : Array[String]) = {&lt;br /&gt;&lt;br /&gt;    val start = System.nanoTime()&lt;br /&gt;&lt;br /&gt;    val r = integrateNormal(Math.sin,0,Math.toRadians(90))&lt;br /&gt;&lt;br /&gt;    val elapsed = (System.nanoTime - start)/1000000000.0&lt;br /&gt;&lt;br /&gt;    println(&amp;quot;Normal answer is &amp;quot; + r + &amp;quot; (&amp;quot; + elapsed + &amp;quot; second(s))&amp;quot;)&lt;br /&gt;&lt;br /&gt;    val start2 = System.nanoTime()&lt;br /&gt;&lt;br /&gt;    val r2 = integrateConcurrent(Math.sin,0,Math.toRadians(90))&lt;br /&gt;&lt;br /&gt;    val elapsed2 = (System.nanoTime - start2)/1000000000.0&lt;br /&gt;&lt;br /&gt;    println(&amp;quot;Concurrent answer is &amp;quot; + r2+ &amp;quot; (&amp;quot; + elapsed2 + &amp;quot; second(s))&amp;quot;)&lt;br /&gt;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-5477678727075080517?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/5477678727075080517/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/10/dual-core-acting-in-scala.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5477678727075080517'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5477678727075080517'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/10/dual-core-acting-in-scala.html' title='Dual core acting in Scala'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-2045442483264856731</id><published>2009-10-17T17:02:00.013+02:00</published><updated>2009-10-21T20:06:16.247+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Test driven you-hee</title><content type='html'>&lt;div align="justify"&gt;In a &lt;a href="http://willowsense.blogspot.com/2009/05/test-drive-your-own-design.html"&gt;previous blog&lt;/a&gt; I described test driven development (or TDD) and hinted that it has many advantages. However, when it comes to graphical user interface (UI) development, programmers expect less benefit from this development technique. The expected benefit outweighs the potential gain and many give the method no more thought. This is concerning because without test-driven development, the value of continuous integration and ultimately the benefit of the Agile method remains unattainable for the team.&lt;br /&gt;&lt;br /&gt;The trouble stems from the fact that the user interface consists of widgets - the forms, buttons, drop-down boxes and so on. These widgets display information to the user and provides him with ways to interact with the application. In order to test this interface, someone that understands the expected behaviour use the widgets verify that the behaviour meets his expectation. This is a difficult and sometimes subjective assessment. Also, the UI test can only be written after the widgets has been implemented; and even then the cost of writing such tests might be too high.&lt;br /&gt;&lt;br /&gt;Does this mean TDD must forever be discarded by UI developers everywhere? Of course not. In fact UI developers should embrace the method with more vigour than server side developers. User interfaces are the visible parts of the application and a change anywhere has a real chance of ending up on the user interface somewhere. In other words: it is a high maintenance area of the application. As such it should be covered with unit tests and refactored often.&lt;br /&gt;&lt;br /&gt;The well trodden road to improve the maintainability of an application is to make sure you have a set of maintainable modules. Each module is a cohesive unit and it is loosely coupled with the other modules. The trick is to keep the user interface modules lean and avoid coupling between these UI modules.&lt;br /&gt;&lt;br /&gt;Consider the one module application that is built entirely with forms. All the persistence, the validation rules, the processes are written in classes that extend the basic form class. This idea was promoted by the older data binding technologies. Only the simplest applications should be built this way. And even simple apllications suffer when new requirements imposes radical changes. Test driven development will not be a first choice for a developer that chooses this 'one module' application architecture.&lt;br /&gt;&lt;br /&gt;Lets look at another plan: a two module application. The one module runs on the server, and the other module is the user interface. At least for the lucky winner of the server side development, test driven development is practical, he can start playing right away. But the user interface developer sits with the problem of validation rules, caching, some process issues and other not so little matters. He must now also retrofit his 'wacky' user interaction ideas on the 'logical' sever side API. You guessed it, no test driven development on the user interface side yet.&lt;br /&gt;&lt;br /&gt;The answer is obviously to have more than two modules. Consider carefully what is meant by the term 'user interface', and divide the identified concerns into a number of modules. While doing this keep the size of the modules that involve widgets to a minimum. Apart from these 'widget modules' all the development work can now follow the test-driven method. The way to end up with these modules is to design them into the architecture from the start and then evolve them as the application grows.&lt;br /&gt;&lt;br /&gt;To migrate to this Utopia, you'll need to make two hard choices:&lt;br /&gt;&lt;br /&gt;* This first choice is to rid yourself from the data-table-driven world and move into the domain-driven way of application development. At least you'll end up with one more module: the domain module. There are many established patterns you can choose from; and test driven development is ideal for domain modules.&lt;br /&gt;&lt;br /&gt;* The next hard choice is to choose a good user interface architecture. In many cases your development environment would lean towards a specific flavour. If it leans toward the bad old flat databinding model; it is time to look around for better tools. Patterns from the model-view-controller and model-view-presenter worlds are well established alternatives. It is important to know the limitations of the particular UI architecture and to understand how to use it well.&lt;br /&gt;&lt;br /&gt;Generally there are always ways to isolate the model aspects, the view aspects and the control aspects of the application. The widgets are in the views; and apart from the view modules TDD works for everything else.&lt;br /&gt;&lt;br /&gt;Keep that chin up, even for graphical user interface development test driven design is within the realms of possibility!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-2045442483264856731?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/2045442483264856731/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/10/test-driven-you-hee.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/2045442483264856731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/2045442483264856731'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/10/test-driven-you-hee.html' title='Test driven you-hee'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-6098546303300049348</id><published>2009-09-21T19:30:00.008+02:00</published><updated>2009-09-21T19:59:36.017+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Say halla to Scala</title><content type='html'>&lt;p&gt;A few years ago I took a functional programming course at university; I immediately liked the idea. Since then I became an eager proponent of functional programming. I am now even more convinced that functional programming will continue to increase its reach into mainstream development. Advancements in C# (LINQ) and the bigger spotlight that F# enjoys is proof that Microsoft is also waking up and smelling the curry.&lt;br /&gt;&lt;br /&gt;It's been a six months out of the Microsoft camp for me. A few weeks ago I started sniffing around in the wild for a Java VM offering that'll do for a functional thinker like myself. The language &lt;a href="http://www.scala-lang.org/"&gt;Scala &lt;/a&gt;was reverently promoted (albeit from a distance) by some of my esteemed colleagues, and I just had to take a closer look. What I found was a pleasant surprise: a first class language that is a viable alternative to Java. Scala is a fully featured object oriented language for the JVM that has been folded nicely with a very usable functional notation.&lt;br /&gt;&lt;br /&gt;Allow me to shamelessly punt the language by listing some key language ideas here (mostly to whet your appetite): &lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Interoperability.&lt;/strong&gt; Scala programs work with Java packages. There is no new standard object library to learn. Scala creates normal JARs, and you can import any old Java JAR and use it without modification. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Implicit typing.&lt;/strong&gt; When the compiler can derive types (which is often enough), there is no need for you to state the obvious. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Better class design.&lt;/strong&gt; In Scala you can declare a "Trait". This is a language construct that allows you to add implemented methods to an interface. Very reminiscent of multiple inheritance. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Local functions.&lt;/strong&gt; Declare a function anywhere - even within the method of a class. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Functions are values.&lt;/strong&gt; Pass a function around as a value and you end up with a very neat solution to event handlers. And that is just the start of the functional magic.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Operator overloading.&lt;/strong&gt; Operators form an important part of the functional paradigm and Scala has a neat solution. Essentially any method that takes one argument is an operator; and yes, you can use operator symbols (such as +,-,++ and many more) as method names. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Matching.&lt;/strong&gt; The idea of functional expression matching is nicely extended to regular expressions and compiled XSLT expression, Ready for use where you need it. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Domain specific language development.&lt;/strong&gt; Put together a parser and interpreter for your own DSL using a powerful grammar framework. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Concurrent programming.&lt;/strong&gt; Use a message oriented programming paradigm built into the language structure to write complex concurrent programs. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You must agree, for any language this is an impressive shopping list. Surely, many more goodies wait to be uncovered.&lt;br /&gt;&lt;br /&gt;On a cautionary note, keep in mind I am just beginning to use the language (at home), some of the claims remain to be verified by yours truly. On the other hand, the Scala project seems very active, and the language is gaining ground. &lt;/p&gt;&lt;p&gt;If you feel the urge to learn something different, Scala might be just the thing for you! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-6098546303300049348?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/6098546303300049348/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/09/say-halla-to-scala.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6098546303300049348'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6098546303300049348'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/09/say-halla-to-scala.html' title='Say halla to Scala'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-5601101567879702943</id><published>2009-08-08T13:55:00.002+02:00</published><updated>2009-08-08T14:13:04.458+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>The profile of your features</title><content type='html'>You ask: "Is this interface user friendly?" and I'll ask "For whom?".  An application that works well for one user may not be usable for another.  A 3D CAD system able to render high resolution graphics is very user friendly for engineers but it is a mundane tool for 3D artists.  Not all applications support the same range of users: some application domains support user profiles with vastly different skills while others have a more homogeneous user set.  There are applications that should support profiles that change for a particular user over time.  For example, a sales application could behave differently for beginners than it would for sales people that have expert domain knowledge.  Most applications should acknowledge the difference between the needs for new application users and those imposed on it by advanced users.&lt;br /&gt;&lt;br /&gt;A good user interface is one that &lt;strong&gt;leverages the strength of its users&lt;/strong&gt; to help them achieve their goals.   If you are in the business of developing tools for software developers you are in luck: you belong to the profile of your users.  The high usability levels of IDEs (as attested by their wide adoption) is proof that knowing your user is actually a good thing. &lt;br /&gt;&lt;br /&gt;You have probably heard it being said somewhere that all software developers are notoriously bad at user interface design.  I despise this generalisation; but many developers actually agree with this assessment.  The cause of this leniency towards us creating such abominations perhaps lies in a personality trait that we share.  Software developers tend to enjoy keeping large and complex mental models in their heads.   This is very useful when you are working in a small part of a very complex system.  Surprisingly to us, not everyone is like this. &lt;br /&gt;&lt;br /&gt;Most people dislike the idea of spending time to refine and perfect abstract  models. They prefer to concentrate on the details that can seen in right front of them.  This is not saying that they are less intelligent; just that they have a different personality type.  For these people the user interface is the system, and the system is the user interface.      To them, the following makes perfect sense: If you want to make the system easier, just fix the interface; and if you want to make the interface easier, just fix the system.  What they get is what they see.&lt;br /&gt;&lt;br /&gt;First impressions last, and the first thing the user sees when the application starts is the primary user interface. This interface strives to match a simplified conceptual model of the application by hiding away many features of the application.  As the UI designer, you have many tools that can be used to hide features.   Here are some of the most obvious  ones listed in decreasing order of exposure:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A &lt;strong&gt;toolbar button&lt;/strong&gt; provides access to features that must be highly visible.&lt;/li&gt;&lt;li&gt;A &lt;strong&gt;menu item&lt;/strong&gt; requires a trivial user gesture to expose features.&lt;/li&gt;&lt;li&gt;A &lt;strong&gt;submenu&lt;/strong&gt; requires a more involved gesture.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Dialogs&lt;/strong&gt; exposes features that are invoked by an explicit user command.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Secondary dialogs&lt;/strong&gt; are exposed from commands available on primary dialogs.&lt;/li&gt;&lt;li&gt;An &lt;strong&gt;advanced mode&lt;/strong&gt;  can be enabled to expose more features for advanced users.&lt;/li&gt;&lt;li&gt;Some applications provides &lt;strong&gt;scriptable functions&lt;/strong&gt; to expose features available to expert users.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As part of your primary user interface design, you need to decide what is on your primary user interface and how the rest of the features will be hidden.  Carefully consider each user profile in your decision:  some user profiles could need alternative primary interfaces.  Also consider how application adapts as the user moves on the beginner-expert profile continuum. &lt;br /&gt;&lt;br /&gt;Next time a user complains about an interface, try not to explain how it "actually" works.  Think out of the box: come up with a visual cue that resolves the complaint on the user interface.  Odds are that you will end up with a more usable application!&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/4245061821217376141-5601101567879702943?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/5601101567879702943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/08/profile-of-your-features.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5601101567879702943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/5601101567879702943'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/08/profile-of-your-features.html' title='The profile of your features'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-9018234068769333355</id><published>2009-07-12T09:46:00.025+02:00</published><updated>2009-07-12T21:12:08.759+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Annotated Java</title><content type='html'>Boilerplate code is a piece of code that is not deemed reusable enough to be abstracted into a function or a class, but it is useful enough to be copied and pasted. After pasting it, minor changes are applied to make it work in its new location. Over time, the boilerplate based code typically becomes a significant part of the source, hindering the cost-effective refactoring when the need arises. In some cases boiler plates can be removed by declarations in configuration files.&lt;br /&gt;An &lt;em&gt;&lt;strong&gt;annotation&lt;/strong&gt;&lt;/em&gt; is a Java language feature that facilitates declarative programming at the source code level. Use this feature correctly and might end up with less boilerplate code, and less configuration files.&lt;br /&gt;When creating your own annotation, you need to decide on the &lt;em&gt;&lt;strong&gt;target&lt;/strong&gt;&lt;/em&gt; and the &lt;em&gt;&lt;strong&gt;retention policy&lt;/strong&gt;&lt;/em&gt; of your annotation. The &lt;em&gt;target&lt;/em&gt; specifies where the annotation can be declared; this could be on a type, a method, a field, a parameter, a constructor, a local variable or another annotation. The &lt;em&gt;retention policy&lt;/em&gt; specifies when the annotation will be used. Annotations can be used on source level (ignored by the compiler), compiler level (ignored by the VM) or run time level.&lt;br /&gt;An annotation can also be &lt;em&gt;&lt;strong&gt;inherited&lt;/strong&gt;&lt;/em&gt; or &lt;em&gt;&lt;strong&gt;documented&lt;/strong&gt;&lt;/em&gt;. When it is &lt;em&gt;inherited&lt;/em&gt;, the values of the annotation on a super class is available on the sub class. The values of a &lt;em&gt;documented&lt;/em&gt; annotation will be printed in the javadoc generated for the annotation class.&lt;br /&gt;&lt;br /&gt;As an example, let's invent a simple scenario: You are implementing an API to you application data. The API is aware of the authenticated user and a set of security levels. The user is authorised to perform only certain methods on your API. The idea is to annotate a method with a security level. A user that does not have the assigned security level should not be able to invoke that method.&lt;br /&gt;Assume we have an &lt;span style="font-family:courier new;"&gt;enum&lt;/span&gt; called &lt;span style="font-family:arial;"&gt;SecurityLevel&lt;/span&gt; with three values &lt;span style="font-family:arial;"&gt;BASIC&lt;/span&gt;, &lt;span style="font-family:arial;"&gt;ADMINISTRATOR&lt;/span&gt;, &lt;span style="font-family:arial;"&gt;SUPER&lt;/span&gt;. For our purposes we simply keep the security level as a property of the &lt;span style="font-family:arial;"&gt;User&lt;/span&gt;, and the logged on user as a property of a &lt;span style="font-family:arial;"&gt;Session&lt;/span&gt; singleton. The code of AnnotationDemo.java looks like this:&lt;br /&gt;&lt;pre style="BORDER-BOTTOM: #999999 1px dashed; BORDER-LEFT: #999999 1px dashed; PADDING-BOTTOM: 5px; LINE-HEIGHT: 14px; BACKGROUND-COLOR: #eee; PADDING-LEFT: 5px; WIDTH: 100%; PADDING-RIGHT: 5px; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; COLOR: #000000; FONT-SIZE: 12px; OVERFLOW: auto; BORDER-TOP: #999999 1px dashed; BORDER-RIGHT: #999999 1px dashed; PADDING-TOP: 5px"&gt;&lt;code&gt;package com.willowsense;&lt;br /&gt;&lt;br /&gt;import java.lang.annotation.*;&lt;br /&gt;import java.lang.reflect.*;&lt;br /&gt;&lt;br /&gt;enum SecurityLevel {&lt;br /&gt;  BASIC, ADMINISTRATOR, SUPER&lt;br /&gt;}&lt;br /&gt;class User {&lt;br /&gt;  final String login;&lt;br /&gt;  final SecurityLevel level;&lt;br /&gt;  public User(String login, SecurityLevel level) {&lt;br /&gt;    this.login = login;&lt;br /&gt;    this.level = level;&lt;br /&gt;  }&lt;br /&gt;  public SecurityLevel getLevel() {&lt;br /&gt;    return level; }&lt;br /&gt;&lt;br /&gt;  public String getLogin() {&lt;br /&gt;    return login;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;class Session {&lt;br /&gt;  static private final Session instance = new Session();&lt;br /&gt;  static public Session getInstance() {&lt;br /&gt;    return instance; }&lt;br /&gt;  private User loggedInUser;&lt;br /&gt;&lt;br /&gt;  public void startSession(User user) {&lt;br /&gt;    loggedInUser = user;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public void endSession() {&lt;br /&gt;    loggedInUser = null;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public User getLoggedInUser() {&lt;br /&gt;    return loggedInUser;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;The annotation needs a property of type SecurityLevel. For now we'll use this annotation during run time. The developer declares the annotation on a method, and we want the annotated values be shown on our javadocs. Let's call the annotation &lt;span style="font-family:courier new;"&gt;@Authorise&lt;/span&gt;. The code for the annotation and an example class that uses it follows:&lt;br /&gt;&lt;br /&gt;&lt;pre style="BORDER-BOTTOM: #999999 1px dashed; BORDER-LEFT: #999999 1px dashed; PADDING-BOTTOM: 5px; LINE-HEIGHT: 14px; BACKGROUND-COLOR: #eee; PADDING-LEFT: 5px; WIDTH: 100%; PADDING-RIGHT: 5px; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; COLOR: #000000; FONT-SIZE: 12px; OVERFLOW: auto; BORDER-TOP: #999999 1px dashed; BORDER-RIGHT: #999999 1px dashed; PADDING-TOP: 5px"&gt;&lt;code&gt;@Documented&lt;br /&gt;@Target(ElementType.METHOD)&lt;br /&gt;@Retention(RetentionPolicy.RUNTIME)&lt;br /&gt;@interface Authorise {&lt;br /&gt;  SecurityLevel level();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class FinancialRepository {&lt;br /&gt;  @Authorise(level = SecurityLevel.SUPER)&lt;br /&gt;  public void deleteAccounts() {&lt;br /&gt;    AnnotationDemo.checkPermission();&lt;br /&gt;    // do the real work here&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see, there is some power in the declarative programming style. The author of the &lt;span style="font-family:arial;"&gt;FinancialRepository&lt;/span&gt; class does not know or care about the details of how authorisation is implemented. However, he still needs to call the &lt;span style="font-family:arial;"&gt;checkPermission()&lt;/span&gt; method. The checkPermission() method uses the stack trace and reflection to identify the calling method. It checks the annotation declared for that method against the logged in user's credentials. Have a look at the implementation in the code below. This code also contains a main method that shows how an authorisation error can be produced.&lt;br /&gt;&lt;br /&gt;&lt;pre style="BORDER-BOTTOM: #999999 1px dashed; BORDER-LEFT: #999999 1px dashed; PADDING-BOTTOM: 5px; LINE-HEIGHT: 14px; BACKGROUND-COLOR: #eee; PADDING-LEFT: 5px; WIDTH: 100%; PADDING-RIGHT: 5px; FONT-FAMILY: Andale Mono, Lucida Console, Monaco, fixed, monospace; COLOR: #000000; FONT-SIZE: 12px; OVERFLOW: auto; BORDER-TOP: #999999 1px dashed; BORDER-RIGHT: #999999 1px dashed; PADDING-TOP: 5px"&gt;&lt;code&gt;public class AnnotationDemo {&lt;br /&gt;  public static void checkPermission() {&lt;br /&gt;    StackTraceElement e[]=Thread.currentThread()&lt;br /&gt;                          .getStackTrace();&lt;br /&gt;    int i;&lt;br /&gt;    for (i = 0; i &amp;lt; e.length; i++){&lt;br /&gt;       if (e[i].getClassName()&lt;br /&gt;             .equals(AnnotationDemo.class.getName())&lt;br /&gt;          &amp;amp;&amp;amp; e[i].getMethodName()&lt;br /&gt;             .equals("checkPermission"))&lt;br /&gt;          break;&lt;br /&gt;       }&lt;br /&gt;    Class&amp;lt;?&amp;gt; c;&lt;br /&gt;    try {&lt;br /&gt;      c = Class.forName(e[i+1].getClassName());&lt;br /&gt;    } catch (ClassNotFoundException e1) {&lt;br /&gt;      return;&lt;br /&gt;    }&lt;br /&gt;    String methodName = e[i+1].getMethodName();&lt;br /&gt;    for(Method m : c.getMethods()) {&lt;br /&gt;      if (m.getName().equals(methodName)) {&lt;br /&gt;        final Authorise auth =&lt;br /&gt;              m.getAnnotation(Authorise.class);&lt;br /&gt;        if (auth == null)return;&lt;br /&gt;        if (auth.level() != Session.getInstance()&lt;br /&gt;                   .getLoggedInUser().getLevel())&lt;br /&gt;          throw new RuntimeException(&lt;br /&gt;              "Unauthorised access by "&lt;br /&gt;              + Session.getInstance()&lt;br /&gt;                .getLoggedInUser().getLogin() +&lt;br /&gt;              " to " +  c.getName() + "." + methodName);&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  static public void main(String[] args) {&lt;br /&gt;    try {&lt;br /&gt;      User u = new User("Rogue",SecurityLevel.BASIC);&lt;br /&gt;      Session.getInstance().startSession(u);&lt;br /&gt;      FinancialRepository r = new FinancialRepository();&lt;br /&gt;      r.deleteAccounts();&lt;br /&gt;    } catch (Exception ex) {&lt;br /&gt;      System.out.println(ex);&lt;br /&gt;    }&lt;br /&gt;  };&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;This sample code demonstrates how to implement an annotation at run time. Look out for places where annotations like these can be used effectively to reduce code and simplify your design.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-9018234068769333355?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/9018234068769333355/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/07/declarative-java.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/9018234068769333355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/9018234068769333355'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/07/declarative-java.html' title='Annotated Java'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-1957924998854847274</id><published>2009-06-13T10:41:00.020+02:00</published><updated>2009-06-14T10:14:09.739+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Get traction on user interaction</title><content type='html'>Like many software developers, I regard user interaction design as a subjective aspect of my work. Right and wrong seem to have little to do with user interfaces and user actions. This grayness that envelopes &lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_0" class="blsp-spelling-error"&gt;UI&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; decisions does not always fit well with a brain that thrives in the black and white binary world. Nonetheless, the user interface is the only thing that other people see of our work. Also, it is very rewarding to help develop an interface that lives up to expectations and receives accolades from its users.&lt;br /&gt;&lt;br /&gt;A far too typical mistake we make is to think of the user as a lesser being than ourselves. This is obviously not true. Users know how to do their work, and they understand the goals they want to achieve with our software. They can easily grasp the breadth of options we lay before them and when given enough leeway they are certainly able to learn how to use any application.&lt;br /&gt;&lt;br /&gt;Once we accept our users as reasonable people, it becomes clear that there might be a list of universal expectations. This list can then be considered for any application. Yes, it is &lt;span id="SPELLING_ERROR_1" class="blsp-spelling-corrected"&gt;intuitive&lt;/span&gt;, but each item in the list that follows requires explicit deliberation when designing the user interaction for your application. &lt;ol&gt;&lt;li&gt;&lt;strong&gt;Don't make me hunt.&lt;/strong&gt; For each view, anticipate the actions the user is most likely to take. Provide quick access to these actions from the view.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't make me guess.&lt;/strong&gt; Consider what important status information is needed by the user, and make sure he in informed when that information changes. Status can be communicated using subtle elements, such as icon states and colours.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't confuse me.&lt;/strong&gt; Keep the interface consistent, not only the look and feel, but also the behaviour. Avoid being too uniform: make sure that things that behave differently also look differently.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't waste my time. &lt;/strong&gt;Save the user's time by combining actions that always follow each other into composite ones. Write &lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_1" class="blsp-spelling-error"&gt;tooltips&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; and help text clearly and concisely. Avoid "Are you sure?" dialogs by introducing an undo facility.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't trap me. &lt;/strong&gt;Give the user the freedom to explore the application safely. Ensure that it is easy return to well known views, and that also actions are &lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_2" class="blsp-spelling-error"&gt;revertable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;. A &lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_3" class="blsp-spelling-error"&gt;revertable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; action is one that can be undone by another action: e.g. the Enable XXX is &lt;span id="SPELLING_ERROR_5" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;&lt;span id="SPELLING_ERROR_4" class="blsp-spelling-error"&gt;revertable&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; if there is a Disable XXX action.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't make me wait.&lt;/strong&gt; When an action will take some time, move it to a thread to allow the user to continue with other things. Remember to provide appropriate feedback (to avoid guessing).&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Don't make me think.&lt;/strong&gt; Expose the conceptual model of the application clearly using appealing metaphors together with images and text cues. Choose the metaphors well and use them consistently. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;User interaction design decisions are very likely to become part of the design considerations of the entire system. It is sometimes impossible to address all the user interaction issues on an older system, or one where the "server-side code" is fixed or inflexible. However, when doing greenfield development, user interaction must be discussed in detail as early as possible.&lt;/p&gt;&lt;p&gt;In summary, things may be less gray if you consider these seven simple guidelines. Keep on rolling out those terrific user interfaces!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-1957924998854847274?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/1957924998854847274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/06/get-traction-on-user-interaction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/1957924998854847274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/1957924998854847274'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/06/get-traction-on-user-interaction.html' title='Get traction on user interaction'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-1491327785606418310</id><published>2009-05-08T10:43:00.016+02:00</published><updated>2009-05-21T20:46:45.702+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Test drive your own design</title><content type='html'>&lt;a href="http://www.agiledata.org/"&gt;Agile&lt;/a&gt; development imposes change on the organisation, the team culture and also on the individual developers. A top-down change is unlikely to reap any benefit if the developers do not change their behaviour at the same time. Developers like me and you must grab the bull by the horns and equip ourselves with Agile methods. Without a deeper understanding of these techniques, it is difficult to motivate change or to steer the change in the right direction.&lt;br /&gt;Test Driven Development (TDD) is one of the cornerstone Agile techniques that is relatively easy to learn from the bottom-up. A developer can add TDD to his repertoire independently, without help from the team or the organisation.&lt;br /&gt;Contrary to first impressions, TDD is not about testing, it is about designing&lt;em&gt; &lt;/em&gt;(read more about Agile design in a &lt;a href="http://willowsense.blogspot.com/2009/03/agile-is-not-fragile.html"&gt;previous blog entry&lt;/a&gt;). As it is with many development processes, the input to TDD is a specification and the output is software. It differs from other processes in that the automated unit tests is the essence of the produced software.&lt;br /&gt;The benefits that TDD brings become reachable when two assumptions are in place. The first is that unit tests are created, and the second assumption is that the TDD design approach is fully adopted. Here are some benefits you can look forward to:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Units tests allow you to verify that the software remains functionally correct after changes are made. &lt;/li&gt;&lt;li&gt;Running these tests help identify some non-functional issues soon after it was caused. For example, an unexpected performance glitch would be picked up when the tests take longer than usual to run.&lt;/li&gt;&lt;li&gt;The design is likely to be better because the code is developed for at least two interfaces (the tests is one and the calling module is the other). The developer designs code that is easy to use because he is the first user of his code. &lt;/li&gt;&lt;li&gt;The test set has a high level of coverage when the work is done. This increases the level freedom developers have to refactor code. Refactoring improves the design over time.&lt;/li&gt;&lt;li&gt;Unit tests illustrate many use cases to developers and as such the tests become an active form of a specification document. Developers look up the code in a test to learn how to use a feature, and also read through test code to gain a deeper understanding of the design.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As a development process, TDD is very simple - it consists of only four basic steps:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Create a &lt;span style="color:#ff0000;"&gt;RED&lt;/span&gt; test. &lt;/strong&gt;Your first task is to create a unit test that fails. Writing this test confirms your understanding of the specification and it highlights exception conditions. You start forming an opinion about the classes and new methods you'll need. During this TDD step, you should implement simple stubs that deliberately fails your test. Keep the scope of the test very small - cover no more than one case of the specification. This step is done when the new test fails for the right reason, and when all old tests succeed.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Quick, get the test &lt;span style="color:#009900;"&gt;GREEN&lt;/span&gt;. &lt;/strong&gt;Implement those stubs you created to get the test to pass. Use the simplest approach possible. Be sure to focus only on getting the test to pass - do not predict alternatives or allow for other cases. If you do, these cases will not have tests associated with them. This step is complete if and only if all unit tests succeed.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Refactor to improve. &lt;/strong&gt;The main idea at this step is to revisit the implementation and make it more elegant. Now that you have a running test harness, you can confidently change the code towards a better design. But, do not get carried away, the principles of &lt;a href="http://willowsense.blogspot.com/2009/03/agile-is-not-fragile.html"&gt;KISS and YAGNI&lt;/a&gt; should always be kept in mind. If you feel the urge to add another use case from the specification, it means you are ready for the next step. The first time you go through step (3), there may be little or nothing to do here. As the system grows and more cases are supported, this step becomes more interesting.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Refine and repeat.&lt;/strong&gt; Take a new use case of the same feature and restart the process from step (1) using that case as specification. If all cases are covered, start with the next feature. If all features are covered, go get a beer: your application is complete. &lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Clearly, the TDD process is incremental and each increment must be kept simple by choosing a small scope. Each cycle should take two hours to implement at most and ideally no more than a few minutes.&lt;/p&gt;&lt;p&gt;TDD is fine when you start a new system, or when you add a new feature, but what about bugs? Even if you are not doing greenfield development, every bug presents a grand opportunity to exercise those TDD muscles. The process for apply TDD for a bug fix should be along these lines:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Create a &lt;span style="color:#ff0000;"&gt;RED &lt;/span&gt;test&lt;/strong&gt;. Start by writing a functional test that reveals the bug. On an old system, creating the first test is likely to be more difficult than it sounds, but after this work, a basic framework will be in place to write more tests easily. While hunting down the bug you may create some tests that succeed. Leave those tests in place and keep on digging. This step is done when you have a failing test.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Quick, get the test &lt;span style="color:#009900;"&gt;GREEN&lt;/span&gt;.&lt;/strong&gt; Now that one failing test is in place it is time to fix it. During this fix-it-quick period, you may develop a theory or two. Write tests for these, either debunking or confirming each theory. At some point you'll find the real cause and all your test will pass after you fix it!&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Refactor to improve. &lt;/strong&gt;You now understand the problem a bit better, and you might want to refactor your solution. Remember to avoid the refactoring of areas in the code that are difficult to test. Refactoring is good, but it is no excuse for messing up working code. &lt;/li&gt;&lt;li&gt;&lt;strong&gt;Refine and repeat. &lt;/strong&gt;It is now time to think about alternative cases that may fail. Write tests for these and when one fails, go to the first step. If all cases are covered, its time for beer: you deserve it.&lt;/li&gt;&lt;/ol&gt;The basic TDD cycle is : &lt;span style="color:#ff0000;"&gt;RED&lt;/span&gt; -&gt; &lt;span style="color:#009900;"&gt;GREEN&lt;/span&gt; -&gt; Refactor -&gt; Repeat. Understanding it is of little use. It is experimentation and practice that add the real value.&lt;br /&gt;&lt;br /&gt;In short: Get TDD into your toolbox!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-1491327785606418310?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/1491327785606418310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/05/test-drive-your-own-design.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/1491327785606418310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/1491327785606418310'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/05/test-drive-your-own-design.html' title='Test drive your own design'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-8775600357697921499</id><published>2009-04-10T10:20:00.019+02:00</published><updated>2009-04-12T17:46:44.744+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Align your compass</title><content type='html'>Not often enough, I take a moment to look at my personal compass. From it I can adjust my heading and remain sure that I am doing the right thing. This is very much needed, especially when the wind is strong, or there is no land in sight (figuratively speaking). Recently, I came across an &lt;a href="http://www.gamasutra.com/view/feature/3960/game_artists_the_three_cardinal_.php"&gt;article&lt;/a&gt; written by Keith Self-Ballard that highlights the rules of success for a budding graphic artist. I feel that Keith presented a universal sense of &lt;em&gt;rightness, &lt;/em&gt;and this &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;inspired&lt;/span&gt;&lt;/span&gt; me to briefly discuss these three rules from a software developer's perspective:&lt;em&gt; &lt;/em&gt;&lt;br /&gt;&lt;em&gt;&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;Rule 1: Manage your ego.&lt;/strong&gt; If you're like me, your ego could be the very thing that started you on this career. With pride I'd show off the cool stuff I created, and I'd make sure every one knows how quickly I get my work done. Bugs were my worst enemy. &lt;a href="http://www.rollingstones.com/discog/index.php?v=so&amp;amp;a=1&amp;amp;id=137"&gt;Wild horses&lt;/a&gt; could not keep me from proving that I had absolutely nothing to do with any bug. This ego thing was good. It motivated me to improve my skills and forced me to keep my eyes peeled for ugly gotchas that bite during testing. Unfortunately, the ego puppy grows up to be an ugly monster. Left unchecked, the big ego stifles your ability to grow and prevents you from reaching your potential. The developer with a small ego is always open to receive advice from others. He accepts responsibility for weaknesses in the software, and he is willing to adapt his own work (and his own ideas) for the greater good. It is definitely worth your while to become an ego-less developer. Don't worry: you'd still be writing good code, but it would be for much better reasons. &lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;br /&gt;&lt;strong&gt;Rule 2: Communicate professionally.&lt;/strong&gt; Bad communication is it the root of many problems; and it can litter your career with many failures. Always look for ways to improve your ability to communicate. A practical way forward, is to adapt your communication style to fit the audience.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;With peers, share knowledge.&lt;/em&gt; &lt;/strong&gt;Dedicate yourself to share and learn from your peers during informal interactions and during formal reviews. When you find something valuable, such as a new development technique, a new feature in your tool set or a new development in your company, share this knowledge with others. Remember that you have a limited time with each individual, because people move on to other jobs. Thus, when the opportunity arises, strive to learn as much as you can from each of your peers.&lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;With&lt;/em&gt; &lt;em&gt;supervisors, understand and recommend&lt;/em&gt;. &lt;/strong&gt;As a developer, we face many types of supervisors. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;These&lt;/span&gt; come in many guises; architects, team leaders, development managers, and so on. With these people we share some responsibility, and they influence what we do and (sometimes) how we do it. Our primary aim must be to understand what is expected from us. Sadly, the world is not perfect - the reality is that situations arise where we strongly disagree with the supervisor. Instead of pointing out the (possibly obvious) problems with her idea, rather take some time to formulate an alternative course of action. Recommend this alternative to your supervisor as a well structured argument. Keep the interaction honest and respect your supervisor's view and also her decision.&lt;br /&gt;&lt;strong&gt;&lt;em&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;&lt;em&gt;With non-developers, change your hat&lt;/em&gt;. &lt;/strong&gt;When interacting with a person from another department, or with your customer, the aim is information exchange. This information is mostly related to expectations and priorities. You can contribute in these interactions by being acutely aware of the other person's point of view. For example, do not ask the marketing manager: "What columns should I add to the costumer table?". Rather, ask: "What information is needed to help you identify potential customers for the new product?". Also, when dishing out information, do not baffle others with technical jargon (this often happens unintentionally). In short: to improve the transfer of information, wear the hat of the other person.&lt;br /&gt;&lt;strong&gt;&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Rule 3: Diversify&lt;/strong&gt;. Sometimes, we think of ourselves as &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;UI&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; developers, or as database developers, or maybe as C# developers. We use these pigeon holes to identify with some development tasks more keenly than with others. Generally, there are tasks that fail to attract our interest or are deemed to be no challenge to our keen intellect. Firstly, we need to acknowledge that these tasks must in fact be done by someone. Then, when such a monkey lands on your back (believe me, it will), approach it with the same level of commitment you'd tackle an &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;absolutely&lt;/span&gt; worthy task. Doing tasks outside your area of core strength is an ideal &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;opportunity&lt;/span&gt; to diversify. You might surprise yourself, and there is no doubt that a more diverse developer is more valuable to a company. So, diversify to improve your career prospects.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;That's it for this blog. In summary, to improve your chances for success mind these three tips: trim your ego, communicate well and diversify your tasks. Simple, isn't it?&lt;br /&gt;&lt;a href="http://headrush.typepad.com/creating_passionate_users/2005/12/are_nice_and_ho.html"&gt;&lt;br /&gt;&lt;/p&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-8775600357697921499?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/8775600357697921499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/03/align-your-compass.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/8775600357697921499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/8775600357697921499'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/03/align-your-compass.html' title='Align your compass'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-753871583835056990</id><published>2009-03-22T09:43:00.021+02:00</published><updated>2009-05-04T20:46:12.135+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Agile design is not fragile</title><content type='html'>A non-&lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;practitioner&lt;/span&gt; may be of the opinion that a software system should be better off after a change. But this is very seldom the case. The effort needed to implement a new feature is always less when hacked in than the effort required to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;redesign&lt;/span&gt; the affected part of the software.&lt;br /&gt;The mark of a good software design is arguably the ability of the designed system to easily adapt to change. Yet, if every change weakens the design slightly, even the perfect system will gradually become inflexible over time. I cannot help but think of it as a law: any software design will naturally decay. This decay takes time; it could take months, years or even decades but &lt;em&gt;decay happens&lt;/em&gt;.&lt;br /&gt;In a paper written by &lt;a href="http://martinfowler.com/articles/designDead.html"&gt;Martin Fowler&lt;/a&gt;, he uses the term &lt;strong&gt;entropy&lt;/strong&gt;&lt;em&gt; &lt;/em&gt;to describe that property of a system that causes the decay. A system with low entropy has a slower rate of decay, and one with a high entropy has a faster rate of decay. A system developed with an up-front design starts with low entropy, and one that is slapped together &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;haphazardly&lt;/span&gt; starts with a high entropy.&lt;br /&gt;If up-front design is so great, why are we not doing it? Here are some issues that make this approach difficult in our industry:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The first is that the design can never contain enough detail to cover all the programming issues. This causes entropy to set in at the initial construction of the system. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;The second problem is that the designer spends so much time designing that he gets no more time for coding. Gradually, he becomes unable to keep up with the changes in tools and technologies, and he could even loose respect for those who code all day long.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The third problem is that requirements change quickly. Every design is based on key requirements. A challenge of design is to decide which kind of changes you'd be able to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;accommodate&lt;/span&gt; easily. Entropy rises dramatically when requirements that introduce &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;unforeseen&lt;/span&gt; changes are implemented.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are surely situations that require up-front design, and there may be some success stories out there. But mostly, the realities of our work environments make this approach impractical. We can continue with (or start with) a haphazard approach, but I do not have the space on this blog to list all the problems associated with that! An alternative solution to face the design challenge is to start building &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_3"&gt;software&lt;/span&gt; using &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_4"&gt;practices&lt;/span&gt; and principles that aim to manage entropy.&lt;/p&gt;&lt;p&gt;Here are the key practices that relate to the system design:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Test Driven Development (TDD) means your software is designed for verification. The practice of test driven development is usually associated with unit tests, but must also be extended to the automated testing of integrated aspects, such as user interfaces. This means you do not have to pick the brain of the designers to make sure a change does not break something. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Continuous Integration (CI) refers to the practice of starting the system build and test process soon after changes are made to the source code. With this in place, a problem is identified minutes after a failure was introduced, making it possible to rectify the situation on the run. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;Refactoring is the practise of making improvements on the design while coding new features. Slogans like "refactor mercilessly" can become reality only where TDD and CI is alive and well. The refactoring guru in your company is the guy that lowers the entropy in the system. He is worth his weight in gold!&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The following principles have a high affinity with the design activity:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Keep it simple stupid (KISS) means that you should not complicate things because of reasons that are not 100% clear. Sometimes we implement things simply because it has worked in the past, or we want to try out a new cool technology. If there is a simpler plan that will do the job, do yourself a favour and follow it. &lt;/li&gt;&lt;br /&gt;&lt;li&gt;You aren't going to need it (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;YAGNI&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;) is really saying that you should not waste effort on something that you "know" will be used tomorrow. Sounds easy, but it is not. As software engineers we tend to think that a system is better because it solves more problems than it requires. The reality is that the new feature is not yet well understood, and you are probably going to get the implementation wrong. It is not worth risking the entropy or the deadline on something like that.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;It seems to me that Agile, as the proponent of these principles and practices, is a move in the right direction. It places more (not less) emphasis on design. Agile methods imply that everybody designs, and &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;acknowledge that&lt;/span&gt; design happens all the time. &lt;/p&gt;&lt;p&gt;In short: Agile does not stifle design, it sets it free! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-753871583835056990?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/753871583835056990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/03/agile-is-not-fragile.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/753871583835056990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/753871583835056990'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/03/agile-is-not-fragile.html' title='Agile design is not fragile'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-7875231828262522810</id><published>2009-03-14T08:59:00.028+02:00</published><updated>2009-03-20T07:18:07.036+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><title type='text'>Spec out the competition</title><content type='html'>&lt;p&gt;Oh, how I wish the question &lt;em&gt;"Have you ever developed software &lt;strong&gt;without&lt;/strong&gt; a specification?"&lt;/em&gt; is a good way to start this blog. Alas, much more apt is this question: &lt;em&gt;"When did you last develop software &lt;strong&gt;with&lt;/strong&gt; a specification?"&lt;/em&gt;. &lt;/p&gt;&lt;p&gt;How is this blatant disregard of functional specification so readily accepted by software developers? Most of them would certainly agree that specifications are very useful, and the righteous would argue that such a thing is absolutely crucial for success. The reason for this disregard seems to be that we are not worthy, our applications are too small, our company is too chaotic and so on. Like the problem of &lt;a href="http://www.nasa.gov/mission_pages/mars/news/mgs-20061206.html"&gt;finding water on Mars&lt;/a&gt;, the problem of producing a specification is often side-handed as a thing that should definitely be done, especially at NASA.&lt;br /&gt;&lt;br /&gt;I find myself ecstatically in agreement with Joel; he wrote &lt;a href="http://www.joelonsoftware.com/articles/fog0000000036.html"&gt;a four part article sequence&lt;/a&gt; on the topic of functional specification. He inspired me to write up some of my own musings on this matter (unavoidably muddled up with the truths eloquently highlighted by the big man). &lt;/p&gt;&lt;p&gt;&lt;strong&gt;What is a functional specification? &lt;/strong&gt;It is a body of knowledge that describes an application from the perspective of the end user. The conceptual model and the user interface aspects of the system are important aspects of this perspective. If you are technically inclined, keep in mind that the functional specification avoids describing how the application is (or will be) implemented. &lt;/p&gt;&lt;p&gt;It must aim to be complete, unambiguous and accurate. In addition, it should be easy to read. A tall order, I know. But, be not dismayed, a specification written by a mere mortal will prove to be worth much more than the time spent writing it down.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;strong&gt;What happens when there is no specification?&lt;/strong&gt; When there is no functional specification the implementation work takes longer; the application ends up with features that are less in number and less in utility; and resulting code is difficult to maintain. Here are some factors that contribute to this banal outcome:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The &lt;em&gt;real problem&lt;/em&gt; is identified too late. Mostly things look easy on the surface, and it is in the detail the devil lurks. In some case the objective of the entire exercise can be missed. As highlighted by a (not so imaginary) friend: "We excitedly set out to solve the problem and quickly wrote an application. Now we have two problems." &lt;/li&gt;&lt;li&gt;Nobody knows what is really going on (and everybody hopes the programmer does). This essentially creates communication problems. The &lt;em&gt;sponsor is unsure&lt;/em&gt; about what he is getting; the &lt;em&gt;quality assurance team cannot test&lt;/em&gt; effectively, and the &lt;em&gt;technical writer wastes his time&lt;/em&gt; by creating manuals that describes everything that is already blatantly obvious to anyone that saw the user interface.&lt;/li&gt;&lt;li&gt;The lack of information translates to lower productivity (and possibly higher irritation level) of the programmer. The constant distraction of people who want to know yesterday's news makes it difficult to focus on the creation of tomorrow's news. As the application grows in stature this overhead becomes more unbearable.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;What then should be in the specification? &lt;/strong&gt;Clearly, the elusive specification should contain information that solves the problems mentioned before. A common misconception is that a specification helps future programmers to understand the system. Although some programmer may be inclined to read the document, mostly they help themselves from the code (design documents has the potential to be absolutely fabulous - but that is a different story). &lt;/p&gt;&lt;p&gt;However, the specification does help the constantly distracted programmer. Instead of a hasty, cryptic comment that most likely does little justice to the application, he can now response with &lt;em&gt;"Would you kindly read the functional specification?" . &lt;/em&gt;The specification should rise to this expectation, and be the reference document for the application. So, here are some ides on its content:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;An &lt;em&gt;overview&lt;/em&gt; that describes the utility of the application to its users. Here, some scenarios of use can be discussed to help the reader to understand the problem the user(s) expect to solve or the activity the user performs with the application as part of a broader process.&lt;/li&gt;&lt;li&gt;&lt;em&gt;Details &lt;/em&gt;about the user interfaces, the validation rules, process invariants and so on. It cannot have too much detail.&lt;/li&gt;&lt;li&gt;A list of &lt;em&gt;non-features&lt;/em&gt; that explains what the application does not do. These could come from discussion held at (formal and informal) meetings, where someone expected a certain aspect to be addressed by the application, but is does not. Another source might be features planned for the future, and behaviours that are viewed as unexpected by someone.&lt;/li&gt;&lt;li&gt;A list of &lt;em&gt;open issues&lt;/em&gt; are very useful during the initial stages of the development. It reminds the reader of some aspects that are still under discussion.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;When is the specification written? &lt;/strong&gt;Here is the really big surprise. Nobody must wait for the specification. Those days are so over, wake up and smell with noses! Today things are supposed to be much more &lt;a href="http://www.agilealliance.org/"&gt;agile&lt;/a&gt;. Likewise, the specification must become agile. &lt;/p&gt;&lt;ul&gt;&lt;li&gt;The basic idea is to &lt;em&gt;start the project with a functional specification&lt;/em&gt; that is on a high level. &lt;/li&gt;&lt;li&gt;Then, as the project continues, &lt;em&gt;update the specification continuously. &lt;/em&gt;&lt;/li&gt;&lt;li&gt;During quality assurance, &lt;em&gt;verify the specification&lt;/em&gt;. &lt;/li&gt;&lt;li&gt;And &lt;em&gt;update the functional specification before &lt;/em&gt;extending the application beyond its initial feature set. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Who writes this thing?&lt;/strong&gt; The problem seems to be that many organisations does not seem to employ the right guy to do this job. However, they did employ you, and my suggestion is that you should do it. It does not matter where you work in the development process - project manager, scrum master, programmer, quality assurance or even chief technology officer. Simply because no-one does it does not mean it should not be done. &lt;/p&gt;&lt;p&gt;Take ownership of the specification and you'll be guaranteed that it will be done. Yes, your time is limited. But, remember only a few minutes per day will be minutes well spent. For your company and for your career. Go for it!&lt;/p&gt;&lt;p&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/4245061821217376141-7875231828262522810?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/7875231828262522810/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/03/spec-out-competition.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/7875231828262522810'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/7875231828262522810'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/03/spec-out-competition.html' title='Spec out the competition'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4245061821217376141.post-6433102988471543741</id><published>2009-01-06T20:00:00.002+02:00</published><updated>2009-02-01T07:59:26.802+02:00</updated><title type='text'>General intelligence for games</title><content type='html'>A game playing agent for Chess can play a chess game, but a &lt;em&gt;general &lt;/em&gt;agent can play any game (or at least learn it). The idea of &lt;a href="http://games.stanford.edu/"&gt;General Game Playing&lt;/a&gt; (or &lt;em&gt;GGP)&lt;/em&gt; is to create a &lt;a href="http://en.wikipedia.org/wiki/Software_agent"&gt;software agent&lt;/a&gt; that plays an arbitrary game. The description of the game is given during runtime. Because the rules of the game is not known &lt;em&gt;a priori&lt;/em&gt;, the knowledge the programmer might derive from the game rules cannot be coded into the agent. The programmer's impossible mission is to build general intelligence into the agent.&lt;br /&gt;&lt;br /&gt;The GGP competition defined by the &lt;a href="http://en.wikipedia.org/wiki/AAAI"&gt;AAAI&lt;/a&gt; limits itself to games that can be described by a state machine. The game has a set of states &lt;em&gt;S&lt;/em&gt;, a set of players, &lt;em&gt;P &lt;/em&gt;(&lt;em&gt;P &lt;/em&gt;has size&lt;em&gt; n)&lt;/em&gt;, a set of actions &lt;em&gt;A.&lt;/em&gt; &lt;em&gt;L = S &lt;/em&gt;x&lt;em&gt; A&lt;/em&gt; identifies the actions allowed in a given state. The mapping to determine the next state, M uses the current state and the action of each player:&lt;br /&gt;&lt;img title="The mapping M" src="http://latex.codecogs.com/gif.latex?M:&amp;space;A_1&amp;space;\times&amp;space;A_2&amp;space;\times&amp;space;A_3&amp;space;\ldots&amp;space;A_n&amp;space;\times&amp;space;S&amp;space;\rightarrow&amp;space;S" border="0" /&gt;&lt;br /&gt;The game starts at the state &lt;em&gt;s&lt;/em&gt; (in &lt;em&gt;S&lt;/em&gt;) and ends when it reaches one of the end states, &lt;em&gt;t&lt;/em&gt;. At this point an outcome for each player is &lt;em&gt;assigned&lt;/em&gt; from a mapping &lt;em&gt;G: S &lt;/em&gt;x&lt;em&gt; P -&gt; [1,100]&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;The number of elements in any of the sets must be finite. However, this does not mean that the games have to be simple. Chess has 10^30 elements in &lt;em&gt;S, &lt;/em&gt;but it can still be described using this simple scheme. However, to a game with this many states, a simple enumeration of states is not possible.&lt;br /&gt;&lt;br /&gt;This is where the Game Definition Language (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;GDL&lt;/span&gt;) comes in. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;GDL&lt;/span&gt; uses a variant of &lt;a href="http://en.wikipedia.org/wiki/First_order_logic"&gt;first order logic&lt;/a&gt;. It is essentially a subset of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;PROLOG&lt;/span&gt;, and in fact &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;PROLOG&lt;/span&gt; can be used to implement a game engine of sorts.&lt;br /&gt;&lt;br /&gt;For &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;GGP&lt;/span&gt; there are some constraints placed on the described game:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The game must be playable. This means there must be a legal move for every player at every state.&lt;/li&gt;&lt;li&gt;The games with one player must be &lt;em&gt;strongly winnable&lt;/em&gt;. There must be some sequence of moves that maximises &lt;em&gt;G&lt;/em&gt;.&lt;/li&gt;&lt;li&gt;The games with more than one player must be &lt;em&gt;weakly winnable.&lt;/em&gt; This means there must be a path that considers joint moves from any state such that each player's goal is maximal (in &lt;em&gt;G&lt;/em&gt;)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;In a single player game, it might be possible to search the game space for a goal state, but in a multi player game, the moves of the other players cannot be determined. Typically, an exhaustive search likely to be out of the question. The problem with heuristic searches is that a heuristic cannot be defined for a general game without knowing the rules. In addition, games dot not have names -- in order to recognise a previously played game, the agent must first assess whether this is in fact the same game. Is is also not possible to learn the strategy of another opponent because the opponents' identity is not shared.&lt;/p&gt;&lt;p&gt;In order to implement the challenge a mediator called &lt;em&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Gamemaster&lt;/span&gt;&lt;/em&gt; is available as a web service. Using a specifically designed protocol the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Gamemaster&lt;/span&gt; controls the game and gives each player a chance to move. If he does not respond in time, a random move is chosen for that player. At the end of the game, each player receives his reward (calculated from G).&lt;/p&gt;&lt;p&gt;Anyone up for a small competition?&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4245061821217376141-6433102988471543741?l=willowsense.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://willowsense.blogspot.com/feeds/6433102988471543741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://willowsense.blogspot.com/2009/01/general-intelligence-for-games.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6433102988471543741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4245061821217376141/posts/default/6433102988471543741'/><link rel='alternate' type='text/html' href='http://willowsense.blogspot.com/2009/01/general-intelligence-for-games.html' title='General intelligence for games'/><author><name>Willem</name><uri>http://www.blogger.com/profile/12795167342888706497</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://4.bp.blogspot.com/_Jzlf8XNIKis/Sg_cs3P3_cI/AAAAAAAAAEM/s5JSeaw-JvA/S220/selfavatar.png'/></author><thr:total>0</thr:total></entry></feed>
