April 2008 - Posts

Career move
30 April 08 03:23 PM | cjlotz | 3 comment(s)

May will be my last month working as a .NET Technology Consultant at Sanlam.  I have accepted an exciting position as Software Architect at Pragma Products where I will join the team beginning of June 2008 to work on the next generation of their software products.  I'm super excited about the company, challenges and the people I will be working with and for the opportunity to finally work in an environment where I can concentrate on using only .NET to build great software.

Filed under:
In Search of Content Collaboration Tools
29 April 08 02:14 PM | cjlotz | 2 comment(s)

image We went through an exercise in the past month or so of trying to select the best platform to use in our company to engage the development communities using mediums like forums/blogs and for managing the content surrounding our development methodology, coding standards and processes through using a wiki.  

We are currently using two different open source products - MoinMoin as a wiki and phpBB for developer related forums.  These products work fine, but the idea was to see whether there are better alternatives available and whether there is not a single product offering that combines wiki/forum functionality with additional collaboration mediums like blogs to create a single source of information going forward.  Having said this, the most important part of the solution for us is the wiki and as such the platform of choice decision was heavily skewed towards the wiki support provided by the solution. 

As the enterprise development landscape in my company is unfortunately mostly geared towards Java, I had to identify and "fight for" different Microsoft solutions that supported these requirements.

ASP.NET Wiki Engines

The first solution that came to mind was Windows SharePoint Services (WSS) 3.0. At the time I was not allowed to investigate MOSS as the product had to be free.  In addition to WSS 3.0, I also previously used two other ASP.NET wiki engines (Perspective Wiki and ScrewTurn Wiki) for managing project related content.  I took these into account as well.

The Wiki functionality provided by WSS 3.0 is IMHO still a bit immature.  I think this has to be expected from a version 1 feature (wiki's are new to WSS 3.0) and by a platform that tries to address the complete content management picture, i.e. support for forums, blogs, projects etc.  This "weakness" is also the biggest strength of WSS 3.0 as it provides a consolidated platform and experience that makes it quite easy to setup a content management solution that includes forums, blogs, projects and much, much more.  The platform itself is extensible as reflected by the ongoing efforts by the community to plug some of the gaps through the Community Kit for SharePoint.  I was quite impressed by the functionality provided by the Enhanced Blog Edition as it provided in my mind most of the missing pieces for a blogging platform, but unfortunately the Enhanced Wiki Edition is still in early days and still missing quite a few important pieces.  The lack of good Wiki support therefore unfortunately ruled WSS out of the picture for us.

Both Perspective and ScrewTurn, as dedicated wiki engines, provide better support for Wiki functionality than WSS 3.0.  Perspective v1 was the first wiki engine I used 2 years back and the results were not too bad.  It has a WYSIWIG editor and for simple scenarios it can be quite effective.  The current v3 Alpha includes a complete overhaul of the Wiki engine with lots of new and exciting features and it seems quite promising.  My only concern is that progress is very slow with the wiki being developed by a single developer. 

These days it seems like ScrewTurn wiki has a lot of momentum behind it as evident through having been declared the winner of Jeff Atwood's donate $5000 to .NET Open Source project.  I'm using ScrewTurn wiki daily and the wiki is frequently being updated with bug fixes and new releases.  There is also an extensive set of community plugins available that add additional missing functionality like AD integration etc.  It unfortunately does not currently support WYSIWYG editing and for us that is a show stopper seeing that our users want to copy/paste content from Word documents and use general RTF editing capabilities.

Final Choice

With no strong MS candidate to bring to the table, I was forced (kicking and screaming smile_wink) to accept a non MS commercial offering!   We opted to buy a Confluence license and I must say that I am very happy with our choice.  Confluence really provides everything you need in terms of a Wiki engine and the price tag is in my opinion quite reasonable given all the features that you get.  The only thing missing from Confluence is the lack of support for forums.  For this I think we'll stick with phpBB and connect the two using an include page macro.

It would be interesting to know whether there are any MS technology based teams that are using anything besides WSS/MOSS/Team System for content collaboration.  What other tools are in your opinion worth looking at?

Filed under: ,
UI Prototyping Tools
08 April 08 09:28 AM | cjlotz | 3 comment(s)

Jeff Atwood's post about UI-First Software Development came just about at the right time as I was looking for some tooling to assist me with a quick prototype that I had to create for a reference application we are building.  For the purposes of this application we needed something more formal than paper prototypes and the tooling should be available for use in different projects within our company.

My favourite UI prototyping tool is MockupScreens.  It is an inexpensive tool that allows you to quickly and effectively create screen mockups using the most common windows controls with sample data and screen navigation included.  You can export the screens as images or as HTML pages with screen navigation to demo to your stakeholders.  There are certainly more professional and expensive prototyping tools available (GUI Design Studio comes to mind), but for simple, yet effective mockups, MockupScreens IMHO gives me the most value for money.  Here is a screen shot of a mockup screen created with MockupScreens.

image

Jeff also links to using PowerPoint 2007 as a wireframe prototyping tool.  I haven't considered using PowerPoint as an option before and I was more interested in the GUUUI Web Prototyping Tools for Visio that some of his readers recommended.  As Visio is already licensed within my company we would not have to buy any additional licenses.  I decided to give it bash.

I must say I was pleasantly surprised by the functionality provided by these templates.  It allows you to draw up a site master that includes the common layout and navigation for your site.  You can then use this master page as the background for your other pages very much like the master page support of ASP.NET.   The sketchy interface widgets also look great and conveys the message of this being a prototype very clearly.

Here is a sample master page for a book store web site:

MasterPage

Here is Browse Catalogue mockup screen based on this master:

BrowseCatalogue

You can easily link up pages together using the hyperlink functionality of Visio and also publish the wireframe to HTML that will include the navigation via the hyperlinks.  It takes a bit longer to create than MockupScreens, but the master page feature is excellent as it allows me to change the common layout in one place and have it correctly reflect in all the other pages!  Excellent stuff! smile_shades

What other tools would you recommend for doing UI Prototyping?

Filed under:
Null Object Pattern
03 April 08 11:01 AM | cjlotz | with no comments

I've been going through some chapters of Agile Principles, Patterns and Practices in C# (which I highly recommend) and I came across a nice trick when implementing the Null Object Pattern that I wanted to share. 

Background

For those new to the Null Object Pattern, I quote from Wikipedia:

In most object-oriented languages, such as Java, references may be null. These references need to be checked to ensure they are not null before invoking any methods, because you can't invoke anything on a null reference. This tends to make code less readable. Instead of using a null reference to convey absence of an object (for instance, a non-existent customer), you use an object which implements the expected interface, but whose method body is empty. The advantage of this approach over a working default implementation, is that a Null Object is very predictable and has no side effects: it does nothing.

It can also be used to act as a stub for testing, if a certain feature, such as a database, is not available for testing.

Martin Fowler also refers to the Null Object Pattern as the Special Case pattern in his Catalog of Patterns of Enterprise Application Architecture.

Implementation

In the application I am currently building, a product catalog can be searched based on price ranges.  For this I created a PriceRangeItem class that is contained within a list provided by a PriceRange class.  The idea is to bind the UI against the list to provide a filter for the products based on the price range.  The list needs to include an "empty choice" item that, when selected, should not affect the search results.  This "empty choice" item is an ideal candidate for a Null Object. 

Here is my implementation:

1 public class PriceRangeItem 2 { 3 private readonly int rangeId; 4 private readonly double rangeFrom; 5 private readonly double rangeThru; 6 private readonly string rangeText; 7 8 public static readonly PriceRangeItem Null = new NullPriceRangeItem(0, double.MinValue, double.MaxValue, string.Empty); 9 10 #region Constructors + Destructors 11 12 public PriceRangeItem(int rangeId, double rangeFrom, double rangeThru, string rangeText) 13 { 14 this.rangeId = rangeId; 15 this.rangeFrom = rangeFrom; 16 this.rangeThru = rangeThru; 17 this.rangeText = rangeText; 18 } 19 20 #endregion 21 22 #region Public Members 23 24 public int RangeId 25 { 26 get { return rangeId; } 27 } 28 29 public double RangeFrom 30 { 31 get { return rangeFrom; } 32 } 33 34 public double RangeThru 35 { 36 get { return rangeThru; } 37 } 38 39 public string RangeText 40 { 41 get { return rangeText; } 42 } 43 44 #endregion 45 46 #region NullPriceRangeItem Class 47 48 private class NullPriceRangeItem : PriceRangeItem 49 { 50 public NullPriceRangeItem(int rangeId, double rangeFrom, double rangeThru, string rangeText) 51 : base(rangeId, rangeFrom, rangeThru, rangeText) 52 { 53 } 54 } 55 56 #endregion 57 }

The trick is to declare NullPriceRangeItem as a nested, private class to prevent external instances of the class being created.  A public static field called Null is then added to PriceRangeItem to expose the single instance of the Null Object that should exist for the application (see line 8).  Other application code can now easily refer to this instance by using code like:

1 if (SelectedPriceRange != PriceRangeItem.Null) 2 { 3 ... 4 } 5

For completeness sake, here is the code for PriceRange class that shows the Null Object being added to the list of price ranges:

1 public static class PriceRange 2 { 3 private static readonly List<PriceRangeItem> list = null; 4 private const string RangeText = "{0:C} - {1:C}"; 5 6 static PriceRange() 7 { 8 list = new List<PriceRangeItem>(); 9 10 list.Add(PriceRangeItem.Null); 11 list.Add(new PriceRangeItem(1, 0, 50, string.Format(RangeText, 0, 50))); 12 list.Add(new PriceRangeItem(2, 51, 100, string.Format(RangeText, 51, 100))); 13 list.Add(new PriceRangeItem(3, 101, 250, string.Format(RangeText, 101, 250))); 14 list.Add(new PriceRangeItem(4, 251, 1000, string.Format(RangeText, 251, 1000))); 15 list.Add(new PriceRangeItem(5, 1001, 2000, string.Format(RangeText, 1001, 2000))); 16 list.Add(new PriceRangeItem(6, 2001, 10000, string.Format(RangeText, 2001, 10000))); 17 } 18 19 public static List<PriceRangeItem> All 20 { 21 get { return list; } 22 } 23 24 public static List<PriceRangeItem> InRange(double rangeFrom, double rangeThru) 25 { 26 return All.FindAll(delegate(PriceRangeItem item) 27 { 28 return item.RangeFrom >= rangeFrom && item.RangeThru <= rangeThru; 29 }); 30 } 31 } 32

Because the ranges with which the NullPriceRangeItem was created with are the minimum and maximum values for a double, you can safely enough use the list without worrying about the NullPriceRangeItem limiting the search results.

Filed under: