March, 2009 Archives
Mar
Software Craftsmanship
by Mikael Lundin in Technicalities
When I say quality is dead, I don’t mean that it’s dying, or that it’s under threat. What I mean is that we have collectively– and rationally– ceased to expect that software normally works well, even under normal conditions.
James post about quality gives me a shrill up my spine. Mention any other kind of product and you would never accept the level of quality that we see in today’s software. No, you would go back to the store and return that faulty product and never choose that brand ever again. You would also tell all your friends about how badly it sucked.
But when it comes to software, bugs are expected. What are bugs really? I would say that they are fabrication errors that never should reach the end consumer or he/she should be able to return the faulty product. Instead, bugs are so wide spread and accepted that we seldom return our software products to the manufacturer, and the manufacturers may downsize their testing and their quality to zero if they want.
Software systems are brittle, very brittle. If fact they are so brittle that if you put a dot, comma or any sign in the wrong place you will meet disaster. Software is also extremely complex. There is no way to overview it all at once, instead you have to break it down into subsystems and view small independent parts of the software and how it communicates with the outside world.
- Software is brittle
- Software is complex
Now is this an excuse? I would like to compare the software developer to a watchmaker. They both work with something that is complex and brittle. And still, watchmakers are much more renowned for their quality and craftsmanship than developers will ever be.
The software industry will not put quality first, until there is a clear way to advertise it and earn money on quality. Until then we will have to live with buggy programs and crashing machines. The software industry needs to grow up, needs to mature and get out of its teens. We want to see a change, and we want it now!
Mar
Keep supporting IE6
by Mikael Lundin in Technicalities
I just checked the IE6 usage on my blog and it’s about 4,3% which is incredibly low. Mostly because it’s only tech people reading my blog. Any other normal Swedish site would have IE6 usage at about 25%. (some higher, and some lower depending on the user base)
The last month our developer community has exploded in this mission that every web site should warn IE6 users and tell them that they are not welcome. This just makes me pissed. In the end you could call this some sort of discrimination as we will stop supporting dumb people, poor people and all the unfortunates that are forced to use this web browser.
Please let me explain my view point
- What browser the user choose is not something for the web developer to oppose. As a consultant it is my obligation to confront my client with the choice of supporting IE6 users or not, because it will take more time and effort to make the web site function properly. It is however not my decision as a developer to say no to 25% of paying customers.
- The majority of the IE6 users are not able to upgrade. They may be senior citizens that does not care about web browsers, but just want it to work. They will get a browser upgrade when their grandchild buy them a new computer to replace that old 266 Mhz PII. The other user base are the companies with huge IT systems that will take years to upgrade. It is not your mission to tell those users what they already know and stop supporting them.
- If you follow web standards the last tweaks to make it look good in IE6 are not overwhelming. So stop complaining about your tools and just get to work.
A couple of weeks ago, Facebook told me that they wouldn’t support the browser that I use. This was probably just a bug in their browser detection system, because it was gone the next day, but do you think that I switched browser to be able to log in that day? No! Do you think that people will upgrade to IE7 before they place an order on your site? No! They will go somewhere else.
Time will take care of this browser just like time took care of Netscape Gold. What we do not need are whining developers. Instead we need a broad support for the user base out there. All IE6 users are welcome to my site. I will not guarantee that it looks exactly like any other browser, but it will be usable and I will not tell you to upgrade.
Mar
Protected: My heart is heavy with technical debt
by Mikael Lundin in Technicalities
Mar
Extending XSLT
by Mikael Lundin in Programming
One thing that I never seem to remember is how to extend my XSLT with extensions. How to include your own namespace and let the transformation engine call my own methods written in C#. It might be hard to remember because I do it once every year, at the most. Now I will write down the procedure here, so that when I google this a year from now, I will find my own blog post.
First, write a class that you want to use in your XSLT. Keep the class public and your methods also.
/// <summary>
/// Default extensions for Mint transformations
/// </summary>
public class XsltExtensions
{
/// <summary>
/// Returns parameter of the current HttpContext.Request
/// </summary>
/// <param name="parameterName">Name of the parameter to retrieve</param>
/// <returns>String.Empty if parameter is not found</returns>
public string parameter(string parameterName)
{
return HttpContext.Current.Request.Params[parameterName] ?? string.Empty;
}
}
My extension above will return a parameter from the current HttpContext. Some would argue that this should be included in the XSLT 2.0 basic functions, but the transformation does not really have any scope in which it is transformed. Could be a web scenario like mine, or a console application where HttpContext would not be present.
Now, in your tranformation code you will have to include this extension class as an argument.
XslCompiledTransform transformer = new XslCompiledTransform(debug);
XsltSettings settings = new XsltSettings(false, false); // document() and script disabled
XsltArgumentList arguments = new XsltArgumentList();
arguments.AddExtensionObject("urn:mint", new XsltExtensions());
transformer.Load(XmlReader.Create(stylesheetStream), settings, null);
transformer.Transform(XmlReader.Create(documentStream), arguments, output);
The magic happens in row 4 and 5. Now it is possible to call this function from within the XSL stylesheet like this.
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:mint="urn:mint">
<xsl:output method="xhtml" encoding="utf-8" indent="yes" media-type="application/xhtml+xml" />
<xsl:template match="/">
<html>
<head>
<title>
<xsl:value-of select="//title" />
</title>
</head>
<body>
<h1>Value of parameter test is: <xsl:value-of select="mint:parameter('test')" /></h1>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Since XSLT is of a very dynamic nature and easy to change, it would seem quite stupid to lock yourself in using only a specified set of extensions. Right? You can solve this by actually loading your XSLT extensions through dependency injection. Let your extension classes implement the following interface.
/// <summary>
/// An extension class for an XSL transformation
/// </summary>
public interface IXsltExtensions
{
/// <summary>
/// Gets the namespace URI that associates this class with a namespace in the xslt.
/// </summary>
/// <value>The namespace URI.</value>
string NamespaceUri { get; }
}
Now you can add extensions as you will in the configuration of your dependency injection framework. I’ve chosen to use Unity for my needs, and my implementation looks something like this.
/// <summary>
/// Loads the XSLT extensions into the argument list
/// </summary>
/// <param name="arguments">The argumentlist that will be used in transfomation</param>
private void LoadExtensions(XsltArgumentList arguments)
{
// Retrieve all implementations of IXsltExtensions
IEnumerable<IXsltExtensions> extensions = ContainerFactory.Instance.ResolveAll<IXsltExtensions>();
// Add all implementations as extensions to the transformation
foreach (IXsltExtensions extensionObject in extensions)
arguments.AddExtensionObject(extensionObject.NamespaceUri, extensionObject);
}
There you have it! ContainerFactory is in my case a singleton that derives from UnityContainer. Let’s hope this will be of any use to you, me or anyone else in a near future.
Mar
Where do you want to goto today?
by Mikael Lundin in Programming
It’s been a while since goto was a valid statement in code and I am proud to say that I seldom ever see it being used anywhere. I haven’t even used it myself except for some very unusual cases.
Why is this? How come goto is such an evil statement? How would you write the following code?
public void LogIn(ILoginService client, string username, string password)
{
int attempt = 0;
LoginAttempt:
try
{
client.OpenConnection();
client.Authenticate(username, password);
}
catch (SecurityException)
{
if (attempt++ < 3)
goto LoginAttempt;
throw;
}
finally
{
client.CloseConnection();
}
}
Just because you have the ring of power doesn’t have to mean that you are completely evil, right? Is it possible to do some good with goto? To find something good in this world, Mr Frodo, that is worth fighting for?
For some perspective on the goto statement, please read the following blog post and get back to me.