Friday, May 27, 2005

Inaccurate self assessment

Our customer is switching from MS MQ to IBM MQ for one of their systems. I've spent some time over the last two weeks developing an abstraction againts IBM MQ to provide less coupled messaging services compared to the earlier solution. When I started I found myself at total loss when trying to estimate the time it would take to bring this baby home safe. To put it simple; I thought I'd need roughly 1.5 the time than it took, and that's including a changed core requirement. I'm quite happy to consider that my self assesment was wrong to the better. I've kept a sustainable pace, doing TDD nearly 90% of the time.

Looking back I think I would have produced better code in shorter time if I had:
1. been more disciplined and gone 100% TDD
2. had someone to pair with (I'm lobbying for that we should try out pairing, I'll keep you posted...)

More good news is that I've stumbled across a chance to be the worst when it comes to the integration stuff and IBM MQ, I've already learnt lots and hoping to pick up a lot more. Had the project been larger I'd probably had the chance to find a master as well.

How to write misunderstandable code

oNodeFrom = oXMLDoc.SelectSingleNode("Accounts/Account[AccountNumber = '" & drpFromAccount.SelectedItem.Value.ToString & "']")
If CDbl(Regex.Replace(oGlobal.FindTag(oNodeFrom, "Amount", "0"), "\s+", "", RegexOptions.IgnoreCase)) < dAmount Then
...
End If


Just having to select a node in an XML document (a web page in this case), clean it up using a regular expression and then casting it to a double to get the disposable amount on the selected account makes me ill. What about something as simple as:
If accountBalance < amountToWithdraw Then
...
End If

which may be refactored to:
If account.Balance < accountTransfer.Amount Then
...
End If

and later on:
account.AddTransfer(...)

etc
etc
etc.

Sigh.

Monday, May 23, 2005

Chaining events in .Net (Sometimes it just isn't so easy)

The solution in my last blog post turned out to only be a semi-working solution since doing the "direct assignment" thingy:
that.MyEvent += this.MyEvent;
only copies the already registered event handlers, which seems perfectly normal when I think about it now. Besides that, the example in my last post was so fictional that it doesn't even work, so here's a working one that illustrates the copy functionality.

class Class1
{
[STAThread]
static void Main()
{
B b = new B();
A a = new A();
a.MyEvent += new X(a_MyEvent);
a.MyEvent += new X(a_MyEvent);
a.Chain(b);
a.MyEvent += new X(a_MyEvent);
b.Fire();
}

public delegate void X();

public class A
{
public event X MyEvent;

public void Chain(B b)
{
b.MyEvent += MyEvent;
}
}

public class B
{
public event X MyEvent;

public void Fire()
{
MyEvent();
}
}
private static void a_MyEvent() { Console.WriteLine("Yihaa!"); }
}

Friday, May 20, 2005

Chaining events in .Net (Sometims it's just too easy)

Had the need to chain events today with some simple decorator-style objects. Scratched my head, tried a couple of solutions, didn't work. Wrote a EventForwarderClass which solved the problem. Sat down to write this blog entry and curse the framework. Then it struck me, did I even try to just add the event to the other event? No, of course not.

public interface A
{
event MyEvent;
}

public class B : A
{
....
}

public class C : A
{
public event MyEvent;
public C(A decorateMe)
{
....do stuff...
A.MyEvent += this.MyEvent;
}
}

Tuesday, May 10, 2005

Initialize smell

If you haven't read how to make your classes Good Citizens, i recommend that you do. The first item states "Keep a consistent state at all times - init() or populate() is a code smell.".

On my screen I have a stack trace that says:

[ManagementException: bla bla bla]
System.Management.ManagementException.ThrowWithExtendedInfo(...)
System.Management.ManagementScope.InitializeGuts(...)
System.Management.ManagementScope.Initialize(...)
System.Management.ManagementObject.Initialize(...)

I'm too lazy (and not bothered enough) to ildasm the whole enchilada but all the initialize methods are private so the code smell doesn't really apply. Despite this I certainly do think it's quite a funny stack trace and to me it signals that if a class (ManagementScope) needs two, different, chained Initialize methods it's a signal that the constructor does a lot of work. Impossible for me to say whether it's good or bad in this case but it does seem a bit smelly to me.

Saturday, May 07, 2005

Reflections on first days of Tiger usage

I've been running Tiger for the last couple of days. Playing with Automator, placing the most important widgets where I want them on the Dashboard, installed Java 1.5, Dashboarding some more, gotten irritated over the fact that Spotllight stole the hotkeys for Quicksilver, used Spotlight a lot less than I thought since Quicksilver is easier, faster and more capable for my usage (except for content searches). But what's the coolest feature? Well, ehrm, without doubt it's the fact that Apple has added https support to the Finders WebDav client. I still think it's kick ass cool to be able to mount your Subversion repositories on the desktop...

Wednesday, May 04, 2005

When a CMS isn't a CMS

Besides from running EPiServer for some of our own websites our company has a few customers for whom we develop and maintain EPiServer sites as well. Since I've been involved in quite a few of those projects I've subscribed to the vendors newsletter. Happily for them (and in a way for us that are partners) they seem to be doing quite well, getting new customers at a constant rate. However as a developer I see one problem with this, my personal opinion is that EPiServer is not a CMS. It's a framework, toolkit and skeleton for building websites.

So what does this mean? Where it a full blown product I'd state that consultants where only needed to do specialized development, for example developing integration with some legacy back end system or providing a custom authentication provider towards the customers unique account database etc. This is not the case. Most of the work consists of developing templates since there's no GUI for that particular task. And yes I'm aware that there are third party extensions that make this possible, but I don't think that's good enough. As a developer, consultant and over all the-right-tool-for-the-job kinda guy I don't like it when a product isn't a product.