Ayende Rahien recently wrote a very well thought through post discussing The Problem of Open Source in the Microsoft World. This is a must-read for any .NET developer who has reached the stage of looking for tools outside of Microsoft. As Ayende describes, a big part of the problem is that there is one major vendor, Microsoft, who not only gives us the basic framework we use to create applications on but also the tools we use to do so with. This means that we can never expect to see built-in support for creating and running NUnit tests. Microsoft has the strength to respond to a need of .NET developers (unit testing their code in this case) by creating their own framework (MS Test) and promoting that, instead of using (or at least including support for) existing de-facto standards (NUnit and MbUnit in this case) already being used by .NET developers.
While I can hope that this might change (as said by others, some IDE competition would be great) I am afraid that it will not happen anytime soon. So what can we do in the meantime? I think it is important for those of us who are using OSS tools (or simply tools from other vendors) to promote them in the .NET community. I am not saying that there always exists a better alternative to Microsoft products, often there does not, but it is important that we help the rest of the community see and evaluate the alternatives. I think some good work is being done here. At öredev, the largest developer conference in Sweden, the .NET track consisted of ten seminars and two half-day workshops. Half of these (one workshop and five seminars) discussed some new technology from Microsoft (Atlas, .NET 3.0, Linq etc), but half of them where mostly about educating the .NET community about professional development using TDD, domain-driven design and AOP. These are competencies that are much more common and standard knowledge in the Java community than what they are in .NET.
At the latest SNUG meeting I did my presentation on testable user interface code and Joel Fjordén and Richard Houltz discussed tools for developer productivity (CodeRush/Refactor and Resharper was also mentioned), coding guidelines (from outside of Microsoft, sort of) and how to enforce them using Joel’s CodeStyleEnforcer plugin. This is what we need to do, getting the .NET community together at meetings and facilitating discussions about professional development and creating better code, by showing what tools are available. This of course includes Microsoft tools, but we should not be limited to this one major vendor.
I did a presentation two days ago at “SNUG”:http://www.snug.se/. The topic was *Testable UI Code*. The title of my presentation was actually “_Cleaning up the mess_” with the subtitle “_How to take control over monstrous UI classes_”. You can download the presentation and code (it was mostly code) in a zipped file.
I started out by showing a demo application, built in the all too common way of simply having all code in one form. Naturally, this was only an example so a real application would have multiple forms and maybe even reusable code in the form of some custom user controls. The problems with this application is that it is difficult to test the behaviour of it. Automating some sort of user interface driver to test it creates tests that are much too brittle and difficult to maintain (there are even those that take a screenshot of the UI and then compare the screenshots created by a test to the “correct” ones!).
I then showed how to take the first step to a better design, by separating the domain logic from the UI class. To my surprise only about half of the audience raised their hands when I asked how many do this in their applications. I guess that it might be that some just did not bother to raise their hands, while others did not really associate with the example I showed (maybe they are using a “Transaction Script”:http://www.martinfowler.com/eaaCatalog/transactionScript.html style rather than the “Domain Model”:http://www.martinfowler.com/eaaCatalog/domainModel.html I showed). This step is what Martin Fowler describes as “Separated Presentation”:http://www.martinfowler.com/eaaDev/SeparatedPresentation.html. My examples are very similar to the ones in Fowler’s texts, so it should be very easy to read his detailed writings and take a look at the examples I created to get a good understanding of the things I discussed in the presentation.
The next step I discussed is to move presentation logic from the UI class to a separate class, often called a presenter. The UI class will simply delegate user input to the presenter class, so I think a simple name for this pattern would be Delegated Input Handling (or similar), although I have never heard it called something like that. The common name for this is of course Model-View-Presenter, but I tried to avoid discussing Model-View-Presenter and Model-View-Controller until later in the talk. The demo (in my code) is called “Passive View”:http://www.martinfowler.com/eaaDev/PassiveScreen.html, since the view (the UI class) contains no logic at all. The view does not do anything else than signalling the presenter when user interaction happens (delegated input handling) and then acts as a getter/setter for the various UI elements that the presenter needs to control.
After this I showed a variation of the step above, where the presenter was simplified by replacing the simple plumbing logic with data binding. To accomplish this the presenter exposes the model (domain objects) to the view so that the view can bind the UI elements to properties of the model. The reasoning for doing this is that data binding is “automatic” and included in the framework, so we can safely use it even though we can no longer test this part of the presentation logic. Martin Fowler calls this pattern “Supervising Controller”:http://www.martinfowler.com/eaaDev/SupervisingPresenter.html (though I would call it Supervising Presenter as he discusses in the article), since the presenter now only supervise things by reacting to user input and letting the view automatically show the current state of the model. However, as a supervisor the presenter will also take control of those situations where automatic handling such as data binding is too difficult or impossible. In those situations it will work with the view in the same way as in Passive View. My demo has an example of this.
Finally, I showed a demo of “Presentation Model”:http://www.martinfowler.com/eaaDev/PresentationModel.html. This pattern is kind of similar in intention to MVP (Passive View and Supervising Controller), but it is differently realized. Here instead of having a presenter we create a separate class, PresentationModel, to hold the current state of the UI. The UI class then does nothing but delegate input handling to the presentation model, and synchronize it’s UI elements with the current state exposed by the presentation model. One of the good things about this is that unit tests become easier to write, since there is no need to fake out the view and test the interaction between the view and the presentation model. With the presentation model completely unaware of the view it is also easy to create the presentation logic (in the presentation model) without any view at all while testing.
Some other relevant links that where in some way mentioned in my talk are listed below.
* “Active Record”:http://castleproject.org/activerecord/index.html is a productive way of setting up a data access layer.
* “MonoRail”:http://castleproject.org/monorail/index.html is an MVC-based web framework for the .NET platform.
* Finally, I mentioned the “Agile öresund”:http://mawi.org/agileoresund/ user group that “Marcus Widerberg”:http://mawi.org/ and I are starting up with some others. If you are interested in meeting quite informally to discuss agile topics, please take a look at the wiki.
* And if you missed it in the text above, you can download the demos and presentation I gave in a zipped file.
On behalf of myself and “SNUG”:http://www.snug.se/, I want to thank those who attended the meeting an hope to see you again at the next meeting which will be in February.
My friend and former colleague “Magnus Mårtensson”:http://blog.noop.se/ recently wrote about “his feelings”:http://blog.noop.se/2006/12/02/When+Quick+And+Dirty+Becomes+Just+Dirty.aspx about “YAGNI”:http://c2.com/xp/YouArentGonnaNeedIt.html and how he instead would like us to follow what he calls “GYCFKSTF” (Give Yourself Credit For Knowing Some Things First). I do not quite agree with what he says (but I guess you knew that already Magnus ;) and started to write a comment, but when it became a bit long I decided to post it here instead.
There is nothing in YAGNI (or other things in XP) that says you cannot “give yourself credit for knowing something”. From the C2 page linked above, here is a relevant quote:
bq. This doesn’t mean you should avoid building flexibility into your code. It means you shouldn’t overengineer something based on what you *think you might need later on*.
I do not interpret YAGNI the same way as Magnus does. I definitely agree that there is a need for some balancing critique of popular things such as agile and terms such as YAGNI. But I think that it will be difficult to come to a conclusion when the different sides have such different interpretations of what they are promoting/critizising. The readers will have to decide for themselves which interpretation they agree with.
What I find that Magnus is doing here is taking something he does not really like (YAGNI), looking at it from some angle and/or interpreting it in one way which makes it look like a bad thing, and then saying that this is the essence of that thing, so naturally it is a bad thing.
To me, YAGNI is just XP’s way of implementing the lean principle of deferring decisions until the latest responsible moment. I do not think that anyone can complain about how this principle works for Toyota and other lean (non-software) companies, but at the same time I realize that what I am doing is just the same thing as Magnus. I am looking at something that I like (YAGNI), from an angle that makes it look like a good thing, and saying that this is the essence of that thing, so naturally it is a good thing. Debates like these will never have any winner, but then again I do not think the meaning of debating is winning. By discussing it everyone is a winner, since hopefully we all learn something in the process. :)
On the smaller scale, YAGNI and TDD says that we should try and solve our problem (get to green) as fast as possible, cutting corners while doing so. This might result in us adding a “public IADAL AAccess” property. However, when we are at green we are encouraged to think, to remove duplication and to improve our design. In this case though we might just be happy with our implementation and add the next test, the one for the IBDAL. Since we need to get to green fast, we would again just add the “public IBDAL BAccess” property. However, now we start to see duplication. At this stage we must refactor to improve our design.
If we do not continuously refactor to improve the code and design, everything will turn into a “BigBallOfMud”:http://www.laputan.org/mud/. Therefore I do not agree that YAGNI will turn into YAGFI (You Ain’t Gonna Fix It!). Agile practices require a lot of disciple, more so than any other method I have encountered, and being professional and always thinking about how the code and design can be improved is part of this.
On the slightly larger scale, YAGNI says that we should “Always implement things when you *actually* need them, never when you just *foresee* that you need them.” It does not say anything about how we should implement things (e.g. “you are not allowed to use a generic version!”). I like to think about it as “do not design for future requirements, but do design for flexibility”. So what would be YAGNI then? Lets say that we “know” that in the future the DALAccess class will need to support feature X (maybe serialization or whatever). We “know” this because there is a story that has been created but not selected for this iteration* which will need this functionality. Lets say that we have done this sort of thing lots of times before, so we “know” that by simply creating an IXable interface and letting our class implement that (or maybe even just returning dummy values for now, the important thing is that the architecture is correct, right?) we will be good for the future. Doing this is violating YAGNI. First of all we do not even know if we need the feature. Implementing it, or at least designing for it now, will take unnecessary time and produce code that might possibly be unnecessary in the end. Next is the question of whether or not this design is the correct one. Based on our experience and what we know now we might be able to say that this design is the correct one. However, if we defer the decision to when we actually need the feature we will know even more and be able to make an even better decision.
So, from my positive point of view, YAGNI is a great guideline that helps me create software that is as simple as possible, but no simpler.
*: ~Again, this is an example of how YAGNI makes more sense for anyone really doing XP, since the fact that there exists a story does not even mean it will ever be selected for implementation.~