Journal of a software dev

June 27, 2009

Should we enforce constructor args?!

Filed under: unit testing — Tags: , — Michael Cromwell @ 10:53 am

 Context

Say we have a Car object:


public class Car
{
    protected Engine engine;
    protected Door[] doors;
    protected Wheel[] wheels;

    public Car(Engine engine, Door[] doors, Wheel[] wheels)
    {
        Check.PreCondition(engine != null, "engine must not be null");
        Check.PreCondition(doors != null, "doors must not be null");
        Check.PreCondition(wheels != null, "wheels must not be null");

        this.engine = engine;
        this.doors = doors;
        this.wheels = wheels;
    }

    public void EnableCentralLocking()
    {
        doors.ForEach(door => door.Lock());
    }

    public void Start()
    {
        engine.TurnOver();
    }
}

The code above is used to demonstrate a context wereby we have an object that takes a number of other collabarators which are then delegated to when certain behaviour is required this is a common event in OO, You can see I use a custom assertion class to make sure the collabarators are not null.

One thing we pick up on is that different behaviours that the Car object is instructed to perform may effect only one collabarator or may effect them all for instance EnableCentralLocking effects the doors collabarating object but has no effect on the wheels or engine.

Unit testing the above

Ok so now we want to unit test the Car object:


[TestFixture]
public class when_central_locking_enabled
{
    [Test]
    public void should_tell_all_doors_to_lock()
    {
        var engine = new Engine();
        var wheels = new Wheel[4];
        var doors = createStubDoors();

        var sut = new Car(engine, doors, wheels);
        sut.EnableCentralLocking();
        doors.All(door => door.Locked);
    }
}

Here I use a state based way of testing the doors have all been locked. One thing is apparent in order to create the Car due to the assertion checks at the beginning I have to create all the collabarators now if I was testing a behaviour that required all of them this is a must however to test the central locking the doors is the only collabarator I need, the creation of the others is just a wasted overhead.

Now this is how I currently create my objects that require collabarators and I was ok with this however recently I was told by a friend to check out a blog by Misko Hevery I was astonished by how well written and the information surrounding good OO and unit testing was, anyhow I came across this post which made me think about whether we should be asserting the collabarators in the constructor or not.

If we remove the assertions our test becomes:


[TestFixture]
public class when_central_locking_enabled
{
    [Test]
    public void should_tell_all_doors_to_lock()
    {
        var doors = createStubDoors();
        var sut = new Car(null, doors, null);
        sut.EnableCentralLocking();
        doors.All(door => door.Locked);
    }
}

hmmm...
We removed the overhead of creating the collabarators not needed for the test however our code is open to NullReferenceExceptions being thrown if were passed a null collabarator, hmmm… a real head scratcher! 

What are the options?

  1. Make the responsibility of making sure objects are created be assigned to a factory object or on an IoC container
  2. Initialize the fields with NullObject values, and use a property to access the field so checks can be made (this would not be enforcable)
  3. Keep the assertions but allow your assertion library to be context aware, at runtime in your unit tests allow it to be in a fall through mode
  4. Keep the assertions and accept the overhead, use Test Data Builder pattern / Object Mother to cut down on repeated code
  5. Move the assertions into the methods, this could cause a lot of DRY violation and extra overhead.

As with most of these things it’s a balance between acheiving 100% defence and overhead required in our unit tests, after looking at the options I could come up with I’m inclined to favour 1 or 3.

What would you use? Do you have any different options about how to balance the 2 out?

June 24, 2009

C# 3.0 Language Features Presentation

Filed under: Uncategorized — Tags: — Michael Cromwell @ 7:54 am

Update: Source code now available from here http://code.google.com/p/mcromwell/source/browse/#svn/trunk/3_0_Features get hold a good SVN client to checkout, such as TortoiseSVN

Yesterday evening I put together a presentation for the Isle of Man devG, I think it went ok overall considering this was my first presentation.

I have yet to make the source code available but once I get round to uploading it I will update this post, If anyone attending has any question’s feel free to drop me an email or leave a comment.

May 24, 2009

Command Query Separation (CQS)

Filed under: best practices, design pattern, oop, software design — Tags: — Michael Cromwell @ 4:58 pm

Introduction

CQS was a term that was coined by Bertrand Meyer and presented itself in his book Object Oriented Software Construction (I haven’t read the book, yet!) the principle states that every method should either be a command that changes state or a query in which case it does not change any state but not both.

In all I agree with the principle I can think of some valid examples that are valid to break it but on the whole it’s makes sense to follow it, however what I want to show in this post is to take this principle and show how it can be applied at various levels rather than just at the method level.

Architectural Level

If we imagine a system which manages lots of amounts of data and the business would like to perform analysis on this data while still providing transactional throughput it would not be uncommon to split the data into separate Online Transaction Processing (OLTP) and Online Analytical Processing (OLAP), this  is a good example of separating the data that will be changing often (OLTP) from the stagnant data that can be analysed (OLAP) I feel this matches strongly to the principle, the benefits gained typically result in better performance and data that reflects the needs of the operations applied to it.

Object Design Level

When we have a complex domain that require numerous behaviours we want to take advantage of domain modelling in our objects by utilising something like DDD to come up with entities, value objects etc… that we can use to represent the domain were working in.

We use these objects to perform transactional operations such as “Submitting an Order” or “Creating a New User” as these represent where we are going to using the behaviours and rules we put together using our objects. What we don’t want to start doing is then using these same objects for displaying result grids on a search screen, this represents a very different usage pattern and if we try to use our objects for this purpose and also for transactional processing we get into a mess quite quickly.

Instead it’s best to take onboard the CQS principle and separate our domain model objects that will be used for out transaction processing from what I think of as reporting or querying objects that are only interested in grabbing data for things such as search screens & reports. So if we were in a issue tracking domain we would probably end up with something like this:


// uses ORM such as nHibernate concerned only with using objects in a transactional
// context does not do any reporting or querying
public class IssueRepository : IIssueRepository
{
	public Issue FindBy(int id)
	{
		// use ORM to get by id
	} 

	public Issue Save(Issue issue)
	{
		// use ORM to save only used when new as object will be tracked
		// for updates automatically
	} 

	public void Delete(Issue issue)
	{
		// use ORM to delete
	}
} 

// probably just uses ADO.NET raw or a light facade on top of ADO.NET
// may use nHibernate but DOES NOT return any transactional objects only
// projections
public class IssueQuerying : IIssueQuerying
{
	public DataTable FindMatchingCriteria(int priorityId, int pageNo, int pageCount, out int virtualCount)
	{
		// use ADO.NET to fill datatable of results, possibly using SP to support paging
		// for older DB
	} 

	public IssueDisplayModel FindAssignedTo(string username)
	{
		// use nHibernate to fill projection object IssueDisplayModel
	}
} 

The benefits we get from separating these 2 concerns:

  1. Our domain model objects are not polluted with lots of getters just to be used for reporting/querying
  2. We can utilise databinding because our querying object returns objects that ASP.NET controls know what to do with (one way databinding only)
  3. Our mapping is simplified as we only need to map our domain model objects to other objects for transactional processing needs not querying/reporting.

Summary

Hopefully this post has shown how we can take the original CQS principle and see how it applies to other levels when developing software from the high level architecture right down to the method level.

May 16, 2009

log4net FallbackAppender – under the hood

Filed under: .net, advice, log4net, log4net contrib, software design — Tags: , — Michael Cromwell @ 6:51 pm

Some Background

I recently put together log4net contrib project up on google code the only item currently up there (though hopefully there should be more stuff from the community up there) is a custom appender I wrote to address the need for having an appender that is clever enough to fallback to other appenders if one fails, this originally came from a forum post of someone wondering how to do it and after some investigation I was that NLog has this built-in.

Investigating how to add it

So my first step was to grab the log4net source and see how I could integrate this appender in, one thing I really didn’t want to do was to change the log4net code and instead allow the appender to be plugged in like you would do normally.

First step was to see how to create an appender that holds other appenders and stumbled across IAppenderAttachable and then the ForwardingAppender which implements it, this interface is what allows you to user the following xml:


<appender name="FallbackAppender" type="log4netContrib.Appender.FallbackAppender, log4netContrib" >
      <appender-ref ref="FileAppender" />
      <appender-ref ref="ConsoleAppender" />
</appender>

And the configuration makes sure that the appender is populated with the referenced appenders. Looking at the behaviour of the existing ForwardingAppender it gave me a lot of what I was after so I inherited from this.

Hitting the main problem

Now I had the FallbackAppender which got most of it’s behaviour from the ForwardingAppender the next step was to setup the following logic:

  1. Get first appender in the collection
  2. Try and append to it
  3. If succeeded exit
  4. Otherwise try and append to the next appender in the collection
  5. Rinse repeat until one succeeds or all are exhausted

On the face of it this seems to be quite simple, loop the appenders and put a try…catch around the call to Append then have some logic in the catch to use the next appender and repeat, something like this:


while (apppenderQueue.Count > 0)
{
    try
    {
        var appender = appenderQueue.Dequeue();
        appender.Append(loggingEvent);
        break;
    }
    catch (Exception thrownException)
    {
        // log to internal log about failure
    }
}

When I tried this and tested against log4net it didn’t work only the first appender was being appended to if I setup the config incorrectly to simulate an issue.

After some digging the issue became obvious the appenders don’t let exceptions bubble up through the stack and instead log to an IErrorHandler that they get via a property from the AppenderSkeleton object they inherit from and with this being the only way to track errors from appenders I had to then impose a limitation.

Adding the AppenderSkeleton limitation to go forward

With the ErrorHandler property coming from AppenderSkeleton being the only way to discover errors I came to the conclusion that I needed to hook into this property luckily the property can be set, this also imposed the limitation that any of the appenders being referenced had to inherit from AppenderSkeleton in the inheritance tree at some point in order to get access to the ErrorHandler property.

Putting in the hooks

The next step I did was to create my own IErrorHandler that simply recorded if an error occurred, and at appender activation I replace each of the referenced appenders ErrorHandler with that one, now the code can see if an error has been raised for a particular appender and move onto the next one.

Summary

I guess this post demonstrates that even if a third party component doesn’t necessarily provide you with an API that makes extending behaviour easy in this example if log4net appenders let the exception bubble up or the Append method returned a bool whether it succeeded or not, there are still tricks we can use to try and achieve it.

May 2, 2009

Obstacles of unit testing & methods to side step them – Part 2: multi-threading

Filed under: TDD, code example, testing, unit testing — Tags: , , — Michael Cromwell @ 7:50 am
Introduction

Unit testing is good. Sure it’s no silver bullet but there is no such thing! Looking back I’m not sure how I managed to work without writing unit tests the number of time having tests has saved me from tracking down bugs isn’t worth thinking about :)

However everything isn’t all rosy once you start unit testing against your code, there are a number of items that can put a spanner in the works, and that’s why I have created this series of posts to try and help other people resolve some of these common issues you may find yourself up against.

  • Date & Time
  • Multi-threading
  • External Dependencies
  • Sharing Static items
Prerequisites
  • You have already been writing unit tests
  • You are familiar with state based testing and behaviour based testing & when best to use either
  • Are familiar with a mocking framework (these examples use Rhino Mocks).
Multi-threading

Let’s face it once we introduce multi-threading things usually get more complicated and trying to unit test multi-threaded code is no exception! Why? Well if we think about how our code is going to be executed it will be ran on the test runner thread by NUnit, MBUnit MSTest etc… And if we have code which is going to perform work on a separate thread this causes a problem because the test runner thread will not know that it should really be waiting for work on the other thread to finish before carrying on, let’s get into some code:

   1: [TestFixture]

   2: public class when_adding_two_ints_together

   3: {

   4:     [Test]

   5:     public void should_give_us_the_correct_result()

   6:     {
   8:         var processor = new Processor();

   7:         var sut = new AddTwoIntsWorkItem(1, 2);

   9:         processor.DoWork(sut);

  10:  

  11:         Assert.That(sut.Result, Iz.EqualTo(3));

  12:     }

  13: }

So for the example I created a simple Processor object and as simple command based interface and a concrete object:

   1: public class Processor

   2: {

   3:     public void DoWork(IWorkItem workItem)

   4:     {

   5:         ThreadPool.QueueUserWorkItem((state) =>

   6:             {

   7:                 workItem.Work();

   8:                 Thread.Sleep(2000);

   9:             });

  10:     }

  11: }

  12:  

  13: public interface IWorkItem

  14: {

  15:     void Work();

  16: }

  17:  

  18: public class AddTwoIntsWorkItem : IWorkItem

  19: {

  20:     protected int first;

  21:     protected int second;

  22:     protected int result;        

  23:  

  24:     public AddTwoIntsWorkItem(int first, int second)

  25:     {

  26:         this.first = first;

  27:         this.second = second;

  28:     }

  29:  

  30:     public void Work()

  31:     {

  32:         result = first + second;

  33:     }

  34:  

  35:     public int Result

  36:     {

  37:         get { return result; }

  38:     }

  39: }

You could imagine that this could represent something more real such as a scheduling object that hold a list of IWorkItem’s and can make calls to them in a async manner, so now we have everything setup we can run the unit test:

image

Hmm… were expecting 3 but getting 0 strange, well not really let’s try to breakdown what’s happening:

image

So our assertion Assert.That(sut.Result, Iz.EqualTo(3)); is being called before the work is done hence we get zero.

So how can we tell the test runner thread to wait till the work is done? Well there’s thread.Join() however we A don’t want to expose the thread object outside of the Processor object as this breaks encapsulation and B In this case we use the threadpool so don’t actually have a new thread created.

With thread.Join() out of the question we need to look for an alternative, luckily the Threading namespace gives a good way of handling this scenario via the AutoResetEvent/ManualResetEvent (the difference being that AutoResetEvent will set it’s state to false after being signalled automatically) that’s great we now have a mechanism for telling the thread to wait however how do we know when to signal the event and allow the test runner thread to carry on? at the moment we have no way of knowing when the Processor has processed the IWorkItem.

I don’t think it’s unreasonable to provide someway of knowing when the DoWork is complete, we can provide a WorkItemComplete event that can be subscribed to:

   1: public class Processor

   2: {

   3:     public void DoWork(IWorkItem workItem)

   4:     {

   5:         ThreadPool.QueueUserWorkItem((state) =>

   6:             {

   7:                 workItem.Work();

   8:                 Thread.Sleep(2000);

   9:                 RaiseWorkComplete();

  10:             });

  11:     }

  12:  

  13:     protected void RaiseWorkComplete()

  14:     {

  15:         if (WorkComplete != null)

  16:             WorkComplete(this, EventArgs.Empty);

  17:     }

  18:  

  19:     public EventHandler WorkComplete;

  20: }

I have introduced the event the next step is to amend our unit test to take advantage of this event and to synchronize the test runner thread with the threadpool thread doing the work:

   1: [Test]

   2: public void should_give_us_the_correct_result()

   3: {

   4:     // this is used to synchronize between this current thread &

   5:     // the thread that performs the work in Processor

   6:     var evt = new ManualResetEvent(false); 

   7:     var sut = new AddTwoIntsWorkItem(1, 2);

   8:     var processor = new Processor();

   9:     

  10:     processor.WorkComplete += (sender, e) => evt.Set(); // signal that work is done

  11:     processor.DoWork(sut);

  12:     // tells current thread to wait till work has been done in Processor

  13:     evt.WaitOne(3000); 

  14:  

  15:     Assert.That(sut.Result, Iz.EqualTo(3));

  16: }

It shouldn’t be too hard to see what’s going on here, I create a new ManualResetEvent and set it’s state to unsignalled, I subscribe to the WorkComplete event via a lambda which simply sets the ManualResetEvent to signalled, after the call the DoWork is made we wait for the ManualResetEvent to be signalled. So let’s give the unit test another go:

image 

Great! that worked a treat one thing to bear in mind is when waiting for the event to be signalled is what timeout to use, in the case above I used 3000 milliseconds you typically want to use something around this figure and should be used as a failover in case the event/method that your expecting to be called isn’t and you don’t get to signal the event, this will prevent the test runner thread from getting stuck.

You should now be more comfortable when having to unit test code that performs work in a separate thread, if you don’t want to expose an event to know when a particular task is finished you could use subclass and override to only provide the event on the test subclass object.

April 24, 2009

Extending the ASP.NET MVC HtmlHelper

Filed under: asp.net mvc, code example — Tags: — Michael Cromwell @ 9:14 pm

The HtmlHelperobject in MVC is great if we want to have a link to an action on a controller we simply do:


<%=Html.ActionLink("my link", "ViewItem") %>

htmlhelper extension manual

And this will create us a link with the text ‘my link’ and will automatically route the href to the ViewItem action on the controller in context. However the HtmlHelper object doesn’t have everything and there are going to be times when you want to have your own HTML rendered on screen, so how can we go about doing that.

The answer lies with extension methods, we can use these to extend the HtmlHelper object and provide us with what were after, in my case it was that I wanted a link but an image enclosed instead of just text.

So here’s the code to achieve this:


public static class HtmlHelperExtensions
{
    public static string ImageActionLink(this HtmlHelper helper, string imagePath, string actionName, string controllerName, object routeValues, object imageAttributes, object linkAttributes)
    {
        var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);
        var anchortagBuilder = new TagBuilder("a");

        anchortagBuilder.MergeAttributes(new RouteValueDictionary(linkAttributes));
        anchortagBuilder.MergeAttribute("href", urlHelper.Action(actionName, controllerName, routeValues));

                var imageTagBuilder = new TagBuilder("img");
        imageTagBuilder.MergeAttributes(new RouteValueDictionary(imageAttributes));
        imageTagBuilder.MergeAttribute("src", imagePath);

        anchortagBuilder.InnerHtml = imageTagBuilder.ToString(TagRenderMode.SelfClosing);
        return anchortagBuilder.ToString(TagRenderMode.Normal);
    }
}

The good thing is that we get a few objects to help us build up the html and to handle the routing side of things rather than having deal with concatenating strings.

Notice that I use the RouteValueDictionary object so that I can use the anonymous type to dictionary trick, the UrlHelper deals with returning the routed URL I just need to provide the controller and what action to invoke, and the TagBuilder makes  light work of creating HTML.

So now from my view I can use it like this:


<%=Html.ImageActionLink(Html.Image("pencil.png"), "UpdateIssue", "ManageIssue", new { id = Model.Id }, new {border = 0, alt = "Edit Issue"}, new { }) %>

I could provide some overloads so that I don’t need to pass empty objects and to accept Dictionaries instead of just object, but you get the idea.

One other thing that’s worth doing is changing the web.config do that your namespace is added automatically to your views that saves having to put the Import on each view that wants to use your extensions, this can be found in the pages section in namespaces.

April 11, 2009

RouteValueDictionary and why we need Hash Literals

Filed under: .net, c# — Tags: , — Michael Cromwell @ 12:26 pm

When working with ASP.NET MVC you will find quite a lot of code that needs key value pairs, especially for routing and providing html attributes, and in most of these places you will see a trend whereby no Dictionary type is created but instead an anonymous type is used:


routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }

So how can it take our anonymous type and create a dictionary from it? Well the object that does the work resides in System.Web.Routing and is called RouteValueDictionary (I think this should be called something like AnonymousTypeDictionary and placed somewhere else as it doesn’t really have anything to do with routing and is used in other sections), this object implements IDictionary<string, object> and has an overloaded constructor that takes a plain object type, it then uses reflection to grab the properties associated with the object and uses the property name as the key and the property value as the value.

So when any of the ASP.NET MVC objects want to create a key value pair they simply pass the anonymous type to the RouteValueDictionary object’s constructor:


// routeValues and htmlAttributes come in as object type.

return htmlHelper.ActionLink(linkText, actionName, null, new RouteValueDictionary(routeValues), new RouteValueDictionary(htmlAttributes));

And voila instant IDictionary<string, object>!

So if this works what’s the problem… well in IMO it’s hack to get round the issue that C# doesn’t have support for hash literals and it would seem I’m not alone, it suffers from a few problems:

  1. Because it uses anonymous types this means the parameter to the method has to be of type object, and from an API point of view that gives us nothing to go as to what needs to be passed in.
  2. It uses reflection to build the key value pairs which takes a performance hit.

For instance take Boo, we could write the following:


routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { "controller" = "Home", "action" = "Index", "id" = "" }

Or by using the open compiler wizardry:


routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    { controller = "Home", action = "Index", id = "" }

Maybe this is asking too much from the compiler and this is as close as were going to get but that would be a shame given the problems above this approach suffers from.

April 7, 2009

Using Windsor for Controller Creation in ASP.NET MVC

Filed under: Castle Windsor, asp.net, asp.net mvc — Tags: , — Michael Cromwell @ 8:10 pm

Given it’s reached v1.0 I finally decided to do some work with the ASP.NET MVC framework and what better way than to take the Issue Tracker which currently runs on Rhino Igloo and refactor it to run on ASP.NET MVC, so expect the next few posts to be related to my findings of how to get things done with it.

First thing is that Rhino Igloo out of the box handles controller creation and uses Castle Windsor to do this ASP.NET MVC by default will use it’s own controller builder, because of this it expects your controllers to have a default no-arg constructor this is no good as I have controllers that need their dependencies passed in, so we need to replace the default controller builder with a version that we can hook up to Castle Windsor.

Now I could go and write my own version this is because the framework is very flexible and was built to allow you to plugin your own  objects, in this case an object that implements IControllerFactory will suffice however why re-invent the wheel when the guy’s over at MvcContrib have done most of the work for us.

Getting the MvcContrib Objects

Head over to to the MvcContrib project on codeplex and grab the extras release, now copy the MvcContrib.dll and MvcContrib.Castle.dll into your external references folder and add a reference where you will be doing the app startup.

Setting the Controller Factory

Inside your global.asax or wherever you do app startup you need to add the following code:


ControllerBuilder.Current.SetControllerFactory(
                new WindsorControllerFactory(this.Container));

Notice that I’m passing the current instance of the windsor container which I get for free because I’m using the UnitOfWorkApplication base class from Rhino.Commons, you will probably have some custom way of managing your container, in which case it just needs to be passed in to the constructor of WindsorControllerFactory.

Wiring up the Controllers

Next we need to make Windsor aware of the controllers, I use Binsor for my Windsor configuration this gives me a nice way to autowire new controllers to Windsor without making any changes:


for type in AllTypes("IssueTracker.Controllers"):
    continue unless typeof(IController).IsAssignableFrom(type)
    component type.Name, type:
        @lifestyle="transient"

Gotta love the conditional expression support Boo has to offer it almost reads like a sentence :) You could also use the XML configuration or programmatic configuration to configure your controllers, and that’s all there is to it!

Kudos to the ASP.NET team for having the foresight to allow these kind of extensions to be plugged in so easily and also to the MvcContrib contributer’s for creating this and support for other IoC containers out there.

April 4, 2009

Finally got with the times and bought a XBox

Filed under: off topic — Tags: — Michael Cromwell @ 10:48 am

I admit it for a lot of the time I have been a PC gamer, I generally don’t spend much time playing games and therefore didn’t see much point in buying a separate console to play games when I have a good specced PC, but given nearly every friend has one and goes on about online play and now the prices are somewhat reasonable I stepped up and bought the XBox 360 Elite, this is the top model so you get most memory for DC (Downloadable Content check me out with the XBox lingo! :) ) and it looks nicer than the white versions!

Anyway my first frustration comes within minutes as I find out wireless connection is not built-in (wtf!) I would expect this as a given. So I forked out the £40 for the wireless adapter (way overpriced IMO) grr! Setting up was a doddle the hardware and the UI is easy to use and I had the standard settings and an account setup in minutes good stuff!

So The Good:

  • The dashboard & Live is perfect MS have really done an excellent job with this, the online experience is exceptional, it’s so easy to join sessions, invite friends to games, setup parties etc…
  • Games in general there’s tons of choice of games out there! The game library for this console is huge
  • Graphics look great for example Bioshock looks amazing!

The Bad:

  • The hardware is the letdown, it just doesn’t feel well built (the headsets feel so flimsy!). And indeed this is supported by the amount of red rings of death people suffer from.
  • I’m not sure of the headset reliability I have had it on a few occasions where it just stopped working, not sure if this is hardware or the software.
  • OMG young whiny online player’s which you never seem to get from online PC gaming.

Overall I’m pleased with my decision and as long as I remember to unplug the headset when I’m in public lobbies to not have to hear some American adolescent with a voice the equivalent to nails on a blackboard then it’s great and I’m having a laugh which is the main requirement.

March 28, 2009

Trace Modeler – Sequence Diagram Application

Filed under: UML, software design — Tags: , — Michael Cromwell @ 3:57 pm

In my last post I outlined some of the anti-patterns I had encountered with using UML for design purposes one of these anti-patterns “Where’s the Behaviour” was centered around overuse of static diagrams instead of focusing on the behavioural aspects of objects, for this I tend to favour sequence diagrams and this post is to review a product I have been using lately to help create sequence diagrams.

I’ll admit that I’m usually a whiteboard or paper & pencil kind of guy when it comes to modeling, however there are numerous times when this just isn’t feasible and you need to have a model in electronic format, this is where this app comes in.

Firstly it’s a Java application therefore making it cross-platform, so Linux and Mac developers aren’t left in the dark and for reference the version I’m basing this review on is v1.6.1.

Trace Modeler Screenshot

The main thing I like about this app is that it works with you instead of against you, the simplicity is comparable to being able to pickup a pen and draw a box. You simply drag on the required artifact (object, comment, message etc…) just like in Visio however unlike Visio you don’t end up having to fight through multiple property dialogs just to be able to set the type of an object for instance. Other UML editors I have used have a similar drag and drop strategy but then use text based conventions to alter the display, Trace Modeler strikes the right balance.

It’s clearly had a lot of work put into it and looks very polished, when moving items around previews are shown to show where they will end up this is a nice feature and gives you some assurance when modifying your model. A lot of the visuals are configurable such as spacing, fonts and colors which helps to give you the diagram styling you’re after. And it has really good support for being able to export your model with various graphics formats being supported.

In most cases I would stick with whiteboard or paper & pencil however when you need to create an electronic sequence diagram I would use Trace Modeler.

For more information and to download Trace Modeler, visit the website http://www.tracemodeler.com/ I recommend taking a look at the  quick 30 second demo.

Older Posts »

Blog at WordPress.com.