Posted on August 28, 2008 10:45 by swilliams

Design matters. The User Interface of an application, be it web or desktop, is one of the most, if not the most, crucial part. Why? Because to the client and/or customers, it is important to them, though they may not know it.

It's been said before, but to the customer, the UI is the application. You might have developed the fastest, most efficient algorithm, but if the user cannot use it, then they just won't.

To be clear, "design" is not necessarily the aesthetic look and feel of an application. Pretty and shiny contribute to the overall sense of design, but do not make up for shortcomings. In fact, there are plenty of command line driven apps that have great design. They ain't pretty, but work great. And once you move a little bit up the learning curve, they become second nature.

EeyoreGood design can be obtained by non-artistic types. One of the most common myths I hear is that people think you have to be be "A Designer" to do good work. The most common response I hear for  a terrible work is "Well, I'm not a Designer."  Yeah, that might be true in HR's filing cabinet, but it just strikes me as a lazy excuse. Or something that Eeyore would say, "Oh well, I'm no good at this. Why even try? I'll just stick to aquamarine and fuchsia." No, your job title might not say "Designer," but it also probably doesn't say DBA, yet you probably have some working knowledge of how SQL works right?

There is a talent aspect to it, but like everything else, talent is worthless without the work to reveal it. And talent is kind of like temperature anyway; there is an absolute zero, but it cannot be achieved in nature (even with quantum effects). In reality, even the most inept can achieve adequate, or even good, design if they apply enough effort.

Where does good design come from then? John Gruber points out that too many people believe that design is just something to worry about at the end of a project. If you say, "Oh, all we have left to do is the UI," then you might as well just drive it off a cliff right then and there.

In the end, a good design ultimately benefits you. The work you do reflects who you are and how your clients/employers see you. And their first impression is the design of an application, so doing a shoddy job is only a disservice to you. It is not easy, but what in software development truly is?



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 26, 2008 21:47 by swilliams

Delegates have come a long way since they were introduced in .NET 1.0. Back then they were only a way to refer to existing methods as variables. 2.0 allowed methods to be inlined, making them "anonymous." The 3.5 Framework does not introduce any new concepts regarding delegates, but it makes writing them much, much quicker and cleaner.

Let's reuse the example from the last post. C# 2.0's syntax for anonymous methods looked like this:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        item.BackColor = index % 2 == 0 ? Color.Red : item.BackColor;
    });
}

The HighliteEven() method can be written with C# 3.0 as:

public void HighliteEven() {
    this.ActOnListView((x, y) => x.BackColor = y % 2 == 0 ? Color.Red : x.BackColor);
}

Whoa, where did that => thing come from? That's the new shorthand for creating an anonymous method. All it does is compresses delegate(Type object){ into something smaller. The (x, y) parameters do not need Type declarations because they are inferred from the delegate's signature as a ListViewItem and a Int32 (you'll even get intellisense on them).

This is what allows you to use all of the slick extension methods added to the standard collection classes:

List<string> stuff = new List<string>();
if (stuff.All(s => s.Length > 10)) {
    Console.WriteLine("all strings have at least 10 characters.");
}
string[] myName = stuff.Where(n => n.StartsWith("Scott"));

Single object parameters do not need parentheses, and delegates with no parameters use empty ones: ().

This type of expression is often called a Lambda. Technically, you can have multiple line lambdas, the convention is to stick with a single one1. Multiple lines of code with this syntax can quickly become messy and hard to read. Stick with the old delegate() { } syntax instead if you need it.

[1. I'm not even going to show or link to the syntax, since you shouldn't use it.]

If you are familiar with Python or Ruby (and others) this style should be familiar to you.

	# a lambda in Python
	sq = lambda x: x * x
	sq(5)
	# returns 25

	# a lambda in Ruby
	sq = lambda {|x| x * x}
	sq.call(5)
	# returns 25

.NET also provides a few prefab helper delegates. Action was provided in the 2.0 framework. It's signature looks like this:

public delegate void Action(T obj);

It has a few overloads to take up to four parameters. So, our sample code up top can be rewritten as:

private void ActOnListView(Action<ListViewItem, int> action) {
	// snip
}

Removing the ItemAction definition.

For methods that need to return something, .NET 3.5 offers several versions of a delegate called Func. The most basic is Func<TResult>(), which takes no parameters and returns an instance of whatever TResult is set to. Func<T, TResult> takes a single parameter, of type T, and also returns a TResult. Like Action, Func provides overloads for up to four parameters. These can all be backported to .NET 2.0, since they don't use any 3.5-only features:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T obj);
// and so on

The various forms of Func are used throughout the LINQ enabled extension methods of the 3.5 Framework.

The single biggest thing to be aware of is that overuse of delegates makes code difficult to read, especially for the neophyte. If you have a particularly hairy situation, say one that has three or more nested generics and a few lambdas, all on one line, consider splitting it apart in order to increase readability. The compiler won't care, but maintainers will appreciate it.

If you have never encountered them before, delegates can feel a little awkward at first, but once you get used to them, especially with C# 3.0's lambda syntax, you won't want to go back.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 24, 2008 10:13 by swilliams

Back in Part 1, we covered the history of Delegates in the .NET Framework. As stated, in 1.1, they were a little too confined to be exceptionally useful. However, in the 2.0 Framework, Delegates were given the ability to be "Anonymous" and could be created on the fly. This allows for more elegant coding, and serves as an introduction to some concepts previously relegated to Functional Programming.

First, an example. In the previous post, this was our basic demonstration of a delegate:

public delegate void SomeFunction(int num);

public void PrintHello(int num) {
    for (int i = 0; i < num; i++) {
        Console.WriteLine("Hello."); 
    }
}

public void Main() {
    SomeFunction func = new SomeFunction(this.PrintHello);
    func(10);
}

Anonymous Methods mean that we do not have to define the PrintHello method as a part of the class, it can be created inline:

public delegate void SomeFunction(int num);

public void Main() {
    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine("Hello.");
        }
    };
    func(10);
}

This in and of itself is useful; it cuts down a few lines of code, but doesn't necessarily add too much value.

Enter Closures. A Closure is "a [method] that is evaluated in an environment containing one or more bound variables." (I'll use OO terminology since this is C# related). What this means is that an anonymous method can refer and use variables defined in the scope surrounding it. Thus:

public delegate void SomeFunction(int num);

public void Main() {
    string s = "This is what will print.";

    SomeFunction func = delegate(int num) {
        for (int i = 0;, i < num; i++) {
            Console.WriteLine(s); // not defined in the delegate, but still valid
        }
    };
    func(10);
}

This of course begs the question of the ages, so what? Why would I possibly want to do something like that? Well, for a simple example, let's say you have a collection of items, say, the items in a ListView, and you have a bunch of operations you want to perform on them at different times. The non-delegate way would be to have separate methods that iterate through the list and do its thing.

public void HighliteEven() {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem li = this.listView1.Items[i];
        if (i % 2 == 0) {
            li.BackColor = Color.Red;
        }
    }
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    foreach (ListViewItem item in this.listView1.Items) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    }
    return items;
}

These are only two methods, but it's not uncommon to have upwards of a dozen, depending on how robust the UI is. If you have an ExtractLong, there's a good chance you'll need an ExtractShort, and probably more ExtractX methods too. Already you can see code duplication in the loops. Anonymous methods let you refactor this code to:

private delegate void ItemAction(ListViewItem item, int index);

private void ActOnListView(ItemAction action) {
    for (int i = 0; i < this.listView1.Items.Count; i++) {
        ListViewItem item = this.listView1.Items[i];
        action(item, i);
    }
}

public void HighliteEven() {
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (index % 2 == 0) {
            item.BackColor = Color.Red;
        }
    });
}

public List<ListViewItem> ExtractLong() {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (item.Text.Length > 50) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

This is better, but we can refactor the Extract method even more. .NET 2.0 also introduces a special delegate called Predicate<T>. If you have used the Array.Find method before, you've used Predicate<T>. A predicate simply executes an expression that returns a boolean. In Array.Find()'s case, it evaluates the object at each index of the array. If the object passes the test provided, it adds it to the return set.

We can use the same idea here to create a generic Extract method which we can give any number of comparers, greatly shortening each ExtractX method.

private List<ListViewItem> Extract(Predicate<ListViewItem> comparer) {
    List<ListViewItem> items = new List<ListViewItem>();
    this.ActOnListView(delegate(ListViewItem item, int index) {
        if (comparer(item)) {
            items.Add(item);
            this.listView1.Items.Remove(item);
        }
    });
    return items;
}

public List<ListViewItem> ExtractLong() {
    return this.Extract(delegate(ListViewItem item) {
        return item.Text.Length > 50;
    });
}

Making an ExtractShort method is just another 3 liner, who's payload is return item.Text.Length < 5; So, rather than having 8 lines of code (at least) per Extract method, you can have 3, which can be a huge savings, and makes testing far easier.

These concepts, and the syntax, may look a little intimidating, but once you have used them for a little bit, you won't want to go back. In the next post, I'll cover the updates to .NET 3.5, and show similar features in a couple other languages.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 23, 2008 15:08 by swilliams

I gave a presentation last night on the topic of improving web design for developers. On the topic of CSS I gave a very simple demonstration on using a non-table based layout. It went well over all, but I didn't have a ton of time to get it perfect and resulted with this.

It works, but wasn't the best I could do (the right column noticeably doesn't extend to the bottom of the content). Christian asked a great question about this, but my brain froze and I wasn't able to come up with a quality answer. Of course this one detail plagued me through the night.

Well, the answer is very simple. Wrap the two columns in a container element (another <div> in this case). Set the overflow property to auto or hidden, adjust the width, accounting for padding, and use the same background color as the sidebar. And presto, you get what I meant to do.

If you'd like to see the markup and style, just view the source of the page.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on July 18, 2008 15:04 by swilliams

Confession time: I love Panic software. They put tons of effort into the UI of their products, and it shows. Even their website shows astonishing attention to detail, and web design isn't even a service that they offer. What gets me the most are the sliding panels on the page for Coda. I peaked at the source code for it and saw:

// Not for redistribution

Hrmph. And then I thought that I could probably reverse engineer what they were doing without copying and pasting their code. Just to be clear, I did not copy a byte of their code; everything here was written entirely by me (except in one case where labeled). To do some of the lifting, I used the Prototype JavaScript library, though you could just as easily do it with JQuery, YUI, or no library at all.

First, the Markup

This is the simplest part. The tabs are just a horizontally positioned list with the bullets removed. And the panels are divs floated sequentially. The idea is that there is a "window" div that displays one of the divs behind it. When a link is clicked, the floated divs slide in the proper direction.

scroller_image

Here is the markup to make it happen:

<div id="main">
    <ul>
        <li><a href="#" rel="scroll">Panel One</a></li>
        <li><a href="#" rel="scroll">Panel Two</a></li>
        <li><a href="#" rel="scroll">Panel Three</a></li>
        <li><a href="#" rel="scroll">Panel Four</a></li>
    </ul>
    <div id="scroll_container">
        <div id="scroller">
            <div>
                <h1>Panel 1</h1>
            </div>
            <div>
                <h1>Panel 2</h1>
            </div>
            <div>
                <h1>Panel 3</h1>
            </div>
            <div>
                <h1>More</h1>
            </div>
        </div>
    </div>
</div>

The only other thing worth mentioning is the rel="scroll" attribute on the anchor tags. This is just used to identify that these links cause a scrolling action to occur, and are used by the JavaScript to easily grab them.

The Style

Styling the HTML isn't too tricky, though there were a couple of small gotchas. My first thought was to set the position of scroller to relative and then use the JavaScript to adjust its left property. This would have worked, but then IE displays all of the scroll panels even if scroller's overflow is set to hidden.

After a bit of snooping I found that I could get the same behavior by adjusting the scrollLeft property on scroller. This manipulates the [invisible] scrollbar.

Scroller's width is large to accomodate all the panels, but could be set to anything greater than or equal to the aggregate width of the panels.

div#main
{
    width: 600px;
    margin: 0 auto;
    height: 800px;
    overflow: hidden;
}
div#main > ul
{
    margin: 0;
    padding: 0;
    width: 100%;
}
div#main > ul li
{
    font-size: 1.4em;
    margin-right: 20px;
    display: inline;
    list-style-type: none;
}
div#scroll_container
{
    width: 600px;
    overflow: hidden;
    height: 740px;
    background: #eee;
}
div#scroller
{
    width: 5000px;
}
div#scroller > div
{
    width: 600px;
    height: 740px;
    float: left;
}

JavaScript - where the magic happens

I took an iterative approach for the JavaScript. First, the most basic way to get "sliding" functionality. The initial design didn't even slide at all, it just moved the panels without an animation.

var scroller = function() {

    var scroll = function(index) {
        var totalOffset = index * scroller.scrollPanelWidth;
        var scrollee = $(scroller.scrollPanel);
        scrollee.scrollLeft = totalOffset;
    }

    var getScrollLinks = function() {
        var links = $$('a[rel=scroll]');
        links.each(function(elem, index) {
            elem.observe('click', function() {
                scroll(index);
            });
        });
    };
    
    return { 
        scrollPanel: '',
        scrollPanelWidth: 0,
    
        init: function(panel, panelWidth) {
            scroller.scrollPanel = panel;
            scroller.scrollPanelWidth = panelWidth || 600;
            getScrollLinks();
        }
    };
}();

This does exactly that. Some of the conventions I'm using here may seem a little weird, but it allows the scroller object to have private fields. To learn more about it, see here.

You can see this in action here.

Functional, but not fancy. I was going to use Script.aculo.us to do the animation, but it does it using the position: relative method described a few paragraphs ago, making IE render incorrectly. Which is kind of a bummer.

So, we'll have to animate this by ourselves. I arbitrarily decided that 500 milliseconds was an adequate time for the animation to take, in 25 frames (for simplicity's sake, pick a number that divides the duration evenly). To accommodate for these values, a couple of properties were added to the scroller object and the scroll() function now does the animating:

    var currentPosition = 0;   
    
    var scroll = function(index) {
        var totalOffset = index * scroller.scrollPanelWidth;
        var desiredOffset = totalOffset - currentPosition;
        var scrollee = $(scroller.scrollPanel);
        var tick = scroller.scrollTime / scroller.ticks;
        var timeIndex = 0.0;
        var inter;
	    
        function animate() {
            timeIndex += tick;
            var delta = desiredOffset / scroller.ticks;
            if (timeIndex > scroller.scrollTime) {
                clearInterval(inter);
                currentPosition = scrollee.scrollLeft;
                return;
            } 
            scrollee.scrollLeft += delta;
        }
        
        inter = setInterval(function() { animate(); }, tick);
    }

See it in action here.

With each tick of the timer the scroller div is moved a little bit in the proper direction. Since the duration remains constant, this has the neat effect of scrolling divs quicker the further apart they are.

At this point we could pat ourselves on the back and call it a day, but there is still a little bit more we could do. If you'll notice in Panic's design, the animation starts slowly, speeds up, then eases into the final position. Kind of like a train leaving the station, and then arriving at the next stop. Script.aculo.us's Effect.Move has the same property. It is these little things that really amp up the aesthetics of an app.

comparison How did they do it? Math! A sine curve has the function of what we're looking for. Our current example has a linear progression. Meaning each tick moves the scroller the same amount. With a sine curve, we get the behavior that Panic and Script.aculo.us have.

Since I haven't actually calculated the sine of anything since school, I decided to just steal borrow someone's code. As mentioned, Script.aculo.us has a sinoidal function. But grabbing a 100k library for a 3 line function is just silly, so I copied it to my own file directly.

var sinoidal = function(val) {
   return (-Math.cos(val * Math.PI) / 2) + 0.5;
}

sinoidal returns a value between 0 and 1, so we just need to multiply it by our desiredOffset to get our delta and tweak how the scrollLeft moves.

var delta = sinoidal(timeIndex / scroller.scrollTime) * desiredOffset;
/* ... */
scrollee.scrollLeft = currentPosition + delta;

And voila, smooth and fancy animation.

Lastly, I created a simple locking mechanism to keep the scroller from getting confused if a link is clicked before the animation is finished. There is still probably work left to be done, but that goes beyond the scope of what I wanted to discuss. So go forth and make great apps!

See the final example in motion.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 20, 2008 13:14 by swilliams

Delegates are a big part of the .NET Framework. They were included since the beginning with .NET 1.0 and have matured since then, but in my experience I don't see them used intentionally too often.

I think the reason for this is because the concept of a delegate is kind of foreign if you have a more procedural background, using mainly languages like Visual Basic or Java, and to a certain extent, C. I certainly hadn't encountered anything like that until I started using C#, and had a difficult time wrapping my head around the concept.

To understand them better, let's take a look at the history of delegates, starting with the positively ancient and crusty .NET 1.0.

At the most basic level, a delegate serves as a way to treat a method as a variable. This means that it can be passed around to different methods, or have its execution delayed until deemed fit. A common reaction to this is "Why would I ever want to do that?" Well, it lets you do some interesting things. For starters, it makes it easier to perform certain kinds of logic at runtime without having to write a great deal of code.

And since every explanation is better with a little bit of code, let's get to it. As stated, delegates have been around for a while. With .NET 1.0, a delegate could only wrap an existing method, nothing on-the-fly:

// This is the definition of the delegate. The return type (void) and 
// arguments (int num) are the signature for any methods that 
// will be wrapped by this delegate.
public delegate void SomeFunction(int num);

// A standard method
public void PrintHello(int num) {
    for (int i = 0; i < num; i++) {
        Console.WriteLine("Hello."); 
    }
}

public void Main() {
    // PrintHello's signature matches what was declared by the 
    // delegate, so it can be used as a variable if needed.
    SomeFunction func = new SomeFunction(this.PrintHello);
    func(10);
}

Again, why does this even matter? The most useful thing about delegates is that you don't need to know which method needs to be called at compile time. One of the classical Design Patterns is the Command Pattern, which let's you abstract a common piece of functionality out to a variable, and pass it around... sound familiar? Delegates are not a complete substitute for the pattern, but can perform similar functionality with far less code. And less code is always better.

Additionally, .NET's event model is based on delegates. The EventHandler is really just a delegate that returns null and takes an Object and an EventArgs. They are also used with some of the asynchronous logic in the framework, BeginInvoke being primary.

For a real-world example, I've seen them used as a neat solution for some of the shortcomings with a Windows Form ToolBar. Back in .NET 1.1, the ToolBar still had many COM underpinnings, and the ToolBarButtons that made up the Bar did not have individual OnClick events on them; you had to handle the ToolBar's ButtonClick event, and pull the Button property from the event's arguments (this was a mess that was replaced with the ToolStrip in .NET 2.0). Once you got this, then you would need to perform some sort of test to determine the appropriate action method. Rather than have a 20 line select statement, one bright co-worker just wrapped the desired method in a delegate and dropped it into the button's Tag property. In just two lines he was able to accomplish what my 20+ did. I call that a bargain.

Here is an example of using delegates to implement a State Machine. This is just the framework for a machine, the strength of it lies in its ability to declare the edges of the graph dynamically.

public delegate Node EvalOp(State s);

public abstract class State {
    // State contains all information about the current position in the graph.
}

public class Node {
    private string _name;
    public EvalOp[] ops;

    public Node(string name) {
        this._name = name;
        this.ops = new EvalOp[] { };
    }

    public string Name {
        get { return this._name; }
    }

    public Node Evaluate(State s) {
        foreach (EvalOp op in this.ops) {
            Node n = op(s);
            if (n != null) {
                return n;
            }
        }
        // If we reach this point, we are at the end.
        return null;
    }

    private static Node _end = new Node("End");

    public static Node EndNode {
        get { return _end; }
    }
}

public abstract class Graph {
    protected Node[] nodes;
    protected Node currentNode;
    protected State state;

    public Graph() {
        this.Init();
    }

    public void Start() {
        for (this.currentNode = nodes[0]; this.currentNode != Node.EndNode; this.currentNode = this.currentNode.Evaluate(this.state)) { 
            this.Step();
        }
    }

    protected abstract void Step();

    // Create nodes and state here
    protected abstract void Init();
}

The basic operation is that each node contains an array of delegates (EvalOp) to define the edges to a new node. The EvalOp takes a State object and determines if it satisfies the requirements of the edge. If it does, it returns the next node to travel to. Each EvalOp is evaluated until the first valid Node is returned. It's not the most robust State Machine ever created, but I wanted to demonstrate delegates rather than State Machines.

I wrote a simple implementation to demonstrate it. There are three nodes, including the EndNode already created by the framework. One is called Odd, and the other is Even, and they switch back and forth depending on the value of State, which is incremented each step of the way, until 100 is reached.

public class ConcreteState : State {
    private int _count;

    // Note the lack of auto-properties in 1.0. Argh.
    public int Count {
        get { return this._count; }
        set { this._count = value; }
    }
}

public class ConcreteGraph : Graph {
    protected override void Init() {
        this.state = new ConcreteState();
        Node odd = new Node("Odd");
        Node even = new Node("Even");

        EvalOp oddTest = new EvalOp(this.OddOp);
        EvalOp evenTest = new EvalOp(this.EvenOp);
        EvalOp finishTest = new EvalOp(this.CountOp);

        odd.ops = new EvalOp[] { finishTest, oddTest };
        even.ops = new EvalOp[] { finishTest, evenTest };
        this.nodes = new Node[] { odd, even };
    }

    protected override void Step() {
        ((ConcreteState)this.state).Count++;
    }

    private Node OddOp(State s) {
        if (((ConcreteState)s).Count % 2 == 1) {
            Console.WriteLine("Odd");
        }
        return this.nodes[1]; // move to the even op
    }

    private Node EvenOp(State s) {
        if (((ConcreteState)s).Count % 2 == 0) {
            Console.WriteLine("Even");
        }
        return this.nodes[0]; // move to the odd op.
    }

    private Node CountOp(State s) {
        return ((ConcreteState)s).Count == 100 ? Node.EndNode : null;
    }
}

More complicated functionality could be added by just creating a new EvalOp delegate (like say, MultipleOfFourOp) and adding it to the proper node[s].

Delegates are not all roses of course. Their biggest shortcoming in 1.1, was that they were too rigid. You needed to have a method defined elsewhere in the app, and you couldn't do some of the neat things that other languages were able to do with similar constructs (typically called lambdas). Fortunately, .NET 2.0 significantly improved delegate's abilities and 3.5 made them extra delicious. I'll write more about them later.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on June 4, 2008 16:51 by swilliams

XML is kind of a neat thing. It is generally human readable and well supported by everything under the sun. But, like everything else in the programming scope, it is imperfect. The problem I have with it is that it seems like everyone is trying to shoehorn technologies into it.

Let's back up a second. XML is a Declarative Programming Language. This means that it describes a process rather than performing one. The most obvious example of this is HTML*. At a basic level, a web page is just a document, and HTML describes its structure well enough. In other words, all it does is state "Here is a heading. Here is a paragraph..." However, when a web page needs to be manipulated or have of some kind of logical flow, something else must be used. I don't know if this is an intended behavior, but it ends up working very well.

[* Technically speaking, HTML came first, and then XML was created as a superset of it.]

Most "classical" programming languages are considered Procedural (or in some circles, Imperative). Rather than describe something, they state the logical flow of execution. These languages have all the control expressions that people are familiar with: ifs, loops, functions, etc.

Each technology performs quite well in its own domain. But the road to pain and suffering begins when things get mixed up, and Procedural concepts are introduced into a Declarative syntax and vice versa.

The biggest example of this woe is an XML based rules engine that I stumbled across not too long ago. Here is how it handles a conditional statement:

<Logic>
  <If>
    <And>
        <Equals leftId="CLIENT_RATING" rightId="PREMIUM_RATING" />
        <Equals leftId="PRODUCT_TYPE" rightId="REGULAR_TYPE" />
    </And>
    <Do>
        <Integer id="DISCOUNT_PERCENT" value="5" />
    </Do>
  </If>
</Logic> 

Just looking at that makes my skin itchy. Just for contrast, here's the same thing in JavaScript:

if (ClientRating == PremiumRating && ProductType == RegularType) {
  DiscountPercent = 5;
}

A common argument for using XML is that it is easier for a lay-person to read, meaning that a programmer is not needed for maintenance. This may be true for smallish files (say 20 lines or so), but what happens when a non-programmer opens up a thousand line build script to make a substantial change? Once a file gets to be sufficiently large, the maintainer needs to have significant knowledge of the domain to make reliable changes, no matter how "easy" it is to read.

Though the bigger problem with this is that the XML here doesn't describe anything, it actually runs the process!

Build scripts are particular offenders here, MSBuild and NAnt being the bigger fish in the sea. In general I like both of these technologies; they provide incredibly useful services to programmers, but editing and maintaining them is arduous. On the surface, a Declarative language would fit in well here. After all, you are just describing a build. But when you get down and dirty, it becomes apparent that these are really procedures being run.

In both pieces of software, there is the concept of "Tasks," These tasks can clean a directory, compile code, publish it, and more. There isn't actually much of a description going on here, the XML is stating exactly what needs to be done. The individual components of a task are really just the lines of a function:

<csc target="exe" output="HelloWorld.exe" debug="false">
  <sources>
    <include name="**/*.cs" />
  </sources>
  <references>
    <include name="System.dll" />
  </references>
</csc>

Could map directly to this JavaScript:

function compile(target, output, debug) {
  var compiler = new Compiler(target, output, debug);
  compiler.sources.push('*.cs');
  compiler.references.push('System.dll');
  compiler.compile();
}

I've been using JavaScript in these examples for a reason: it lends itself well to the simple procedural programming that is described here. It's fairly lightweight, has a straightforward syntax (especially when certain conventions are forced on it), and most programmers already are familiar with it, due to the ubiquity of it on the Internet. You could have a whole scaffolding of a build script that looks like this:

// Build variables
var codeDir = 'c:\code';
var outDir = 'c:\output';

// Entry Point
function init() {
  clean();
  getFromScm();
  compile();
  test();
  deploy();  
}

// Error Handling
function onError(msg) {
}

// Tasks
function clean() {
}

function getFromScm() {
}

function compile() {
}

function test() {
}

function deploy() {
}

If JavaScript isn't your thing, there is a fascinating build utility out there called Rake. It is billed as a replacement for the old Unix and C Make utility. It does something similar to my JavaScript example, and has the power of Ruby behind it.

For programmers, and even laymen, this is readable and maybe even intuitive. Additionally, you have hosts of technologies that go with a popular procedural languages. Can you create a full battery of unit tests for your build script? Quickly? Can you easily attach them to a debugger? Perform static analysis? All of those things would be useful in a build script, but are difficult to do with XML.

Well then, what exactly is XML good for? In my experience I have found that XML is the "right" solution when you do not have to do any extra processing to handle it. Yes, most modern libraries have XmlReaders and such, but it is still a dreary task to using them to parse a large document. Perhaps the best example I can give is .NET's XmlSerialization modules. With a few lines of code, you can turn an object into an XML node, and then back again. No mucking about with Readers, XPath, or anything. And generally, the resulting XML is lightweight enough that it isn't a huge chore to modify it if needed.

The rule of thumb here is that XML is good when you do not need to put forth a huge effort to use it. Remember, things like this are supposed to be increasing our productivity, not lowering it.

I hope that I didn't come down too hard on XML here. Again, I think it is an incredibly useful tool, and there have been plenty good technologies based on it, I just think that you need to be careful not to use it (or any other "hot" commodity) in the domains that it is simply not suited for.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 13, 2008 16:16 by swilliams

One of the hip new features of C# 3.0 is the built in support for lambdas:

Func<int> sq = x => x * x;
sq(5); // equals 25

This is very fancy, but sometimes you need to perform a lambda that has no argument. The syntax for that is simply "()".

Func<object> doStuff = () => Console.WriteLine("stuff has been done"); 
doStuff();


Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 13, 2008 09:01 by swilliams

Sogeti Phoenix screenshot We've recently updated the theme of our site! Originally it was using the default "Standard" theme included with BlogEngine.Net. As with most default things, it needed a significant facelift. After poking around the other themes included with the distribution, I saw that Terrafirma had similar colors to ours.

I did a little tweaking with the fonts and made some fixes regarding dates, and arrived at what you see now. The only thing missing was a fancy header logo. As luck would have it, I came across a fantastic resource of free blog headers at smashingmagazine.com. Again, I picked one of the headers that matched the colors we have, and added some Sogeti branding.

All in all, I'm very pleased with the end result. I know that there are still display issues with IE 6, but for all other modern browsers, it looks pretty good. If you do find an issue, please either add a comment here or send us an email.



Digg It!DZone It!StumbleUponTechnoratiRedditDel.icio.usNewsVineFurlBlinkList

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted on March 10, 2008 19:03 by swilliams

Last time, we tweaked our code to make it a little easier to understand and maintain. So that means we get to dirty it up again!  Our current object model has very simple mapping of one table to one class, with no associations between them. In the real world, this doesn't happen too often (and if it does, you are probably doing something wrong). A relational database has relations. Crazy, yes, but it means our model must be able to handle that.

Let's say then, that the Person object can possess all of the TpsReport objects they have created. To represent that, we'll need to update three things, our table structure, the classes, and the mapping file.

More...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5