When Object-Oriented Rendering is Too Much Code

Let's say you wanted to generate and render this XML fragment:

Here's a fully object-oriented way of building it:


This is a companion discussion topic for the original blog entry at: http://www.codinghorror.com/blog/2006/06/when-object-oriented-rendering-is-too-much-code.html

But, but, but, what happens when your params have a literal quote in them someday?

Those two code fragments don’t show object oriented vs structured programming, they show using one function (which implements a simple parser) verses using many functions to do the same thing.
(Well a similar thing, I’m guessing the second piece of code will not handle any changes to ‘id’ or ‘code’ as well as the first)
Not that I disagree that an OO only policy is a bad idea, it’s just that the example doesn’t show it.

So, what happens to values that need escaping in the string example?

BOOM

What you get from a library is domain knowledge that you as a library user may not need to care, or even know about.

But I agree that the first example is very verbose compared to what it does. So, the interface sucks. Are there no XML libraries with simple interfaces for solving simple problems?

/J

So, what happens to values that need escaping in the string example?

So use an existing function that sanitizes and escapes user input for output in XML. No big deal.

Are there no XML libraries with simple interfaces for solving simple problems?

Here’s the scary part-- that IS the simple XML library! I could easily construct a much more verbose example using other Xml* objects.

There is nothing wrong with object-orientation.

The basic problem you have is imperative versus functional-programming (composition) styles for constructing data.

If you used LINQ, you would have both OOP and functional styles combined.

Seems like this could be partially solved using code gen to create the writer code from an xml snippet.

Also, depending on the situation, serialization is another OO way to get the XML you want without using the writer or string-building approach.

Jeff,
I’m all for the simplest thing that could work, but the example above is not going to cut it.
As the other people mentioned, your solution would generate invalid XML in a range of scenarios.
Yes, you can handle that, but pretty soon you’ll find yourself writing more code than the original way.
Worse, you will fix each issue as a bug fix that would never come up if you used the XML API from the start.

your solution would generate invalid XML in a range of scenarios

How so? This is scaremongering! If we modify it this way…

String.Format(s, XmlEncode(“1”), XmlEncode(“usr”));

(Which, by the way, is only necessary if these fields are derived from user input.)

I don’t see a “range of scenarios” where the XML will be invalid…

I think what’s missing in the conversation is the generating XML or HTML via string building is error prone. There’s a tremendous amount of ill-formed XHTML out there that is caused by string builders. But I agree, XML Write is too complex.

generating XML or HTML via string building is error prone

Let me play Devil’s Advocate for a minute.*

And generating XML or HTML via umpteen billion Xml*.* methods isn’t error prone?

I had to experiment quite a bit with the Write commands to get the output XML to match the requirements. Was that error prone? You bet it was. Particularly compared to just cutting and pasting into a string.

  • I know, also known as the entirety of my life. Har har.

This has successfully argued that if you want to write a 4-line XML fragment, using the XmlWriter is overkill.

In most trivial examples, we find that using powerful libraries takes more work than not using them.

However, what would this turn into when the example becomes non-trivial? How easy would maintainance be if an element has 10 attributes and you want to remove the 5th one?

Personally, I’ve got enough things to worry about to be distracted by getting the XML syntax right.

How so? This is scaremongering! If we modify it this way…
String.Format(s, XmlEncode(“1”), XmlEncode(“usr”));

What are you talking about? Scaremongering! LOL.
The “improved” code you wrote is a mess, and prone to mistakes (you have to remember to escape every time otherwise you risk introducing bugs).

There is nothing wrong with a fully OO aproach to programming. As Johan L pointed out, its just the interface that sucks.

Once you realise its just a poor interface, pull your finger out and write your own wrapper Class for XmlWriter that allows you to program in a succinct and elegant fashion.

Then you get THE BEST OF BOTH WORLDS!!

For an example of a wrapper class that achieves this level of elegance in writing DOM based code in an efficient OO manner see DOM JS http://dom.simplesideias.com.br/

A wrapper for XmlWriter?.. you might have to roll your own…

In ruby, the code looks much better:

a href="http://www.rafb.net/paste/results/x9VHuZ53.html"http://www.rafb.net/paste/results/x9VHuZ53.html/a

(from Builder documentation)

After living some time with ruby, each time I go back to C# or Java I just hate the overhead of having to declare everything by type even if I don’t really need the type safety.

I’ve been on any number of HTML projects with all kinds of different programmers over the years.

I’m yet to see a programmer who always remembers to escape their output correctly with string concatentation. This includes me, and I’m very aware of the issue. Encoding issues like that are probably the number two cause of security vulnerabilities; with that approach, you forget once to escape correctly, and you’ve got a potential XSS security vulnerability on your hands.

On the other hand, I’ve found that a full OO-esque approach has had comprehension difficulties that make it tough to just throw a web page at somebody and expect them to work on it. Personally, I love the OO approach because it allows you to create functions for recurring snippets (and I wouldn’t be caught dead using a language or library that was a quarter than verbose; I’ve written libraries in languages where the penalty is about two chars an “element” (tag, attribute, etc.), which came back almost instantaneously due to the functions I got to write), but this is also something I’ve experienced people having fun with.

Where I work now, the lead developer and I went back and forth on this issue, and we settled on a compromise I’ve found acceptable, and has been working for us (that is, people aren’t accidentally writing XSS vulnerabilities left and right): We changed the default escaping mechanism to be XML/HTMLEscape, instead of straight concatenation. We’re in an ASP-esque enviroment that uses [%= %] as the shortcut for rendering, and then we added [%! %] for “no escaping” inclusion. Square brackets are used because there is no indication of whether this comment box will take HTML, and there is no preview. (And we’d use the ASP templating to do that substitution, not string manipulations in the program.)

This has avoided the very real objections raised about crossing encoding planes (very dangerous, should not be underestimated!) while still retaining the practical essense of the second solution.

Jeff,

Your code sample:

string s =
2 @“status code=”"{0}"“
3 data
4 usergroup id=”"{1}"" /
5 /data";
6 return String.Format(s, “1”, “usr”);

Always produce invalid XML because the status tag has no end bracket and also has no closing tag.
This was propably just a typo, but it just confirms that not using an XML API is error prone.
The benefit of using XML APIs is that is always generate well formed XML. Using string to build XML can introduce bugs that are only discovered at runtime.

I just checked your code again and it looks fine.
I guess there was something with my browser because I could swear the closing tag and end bracket were missing before I post my incorrect comment.

there is no indication of whether this comment box will take HTML

I guess the “Your comments: (no HTML)” text is hard to see. I’ll modify the template…

This was propably just a typo, but it just confirms that not using an XML API is error prone.

Sure. You’re right, I corrected it. But I think having literally 8x the amount of code is also error prone. More code = more errors.

Did you guys see the Ruby example linked above?


builder = Builder::XmlMarkup.new(:target=STDOUT, :indent=2)
builder.person { |b| b.name(“Jim”); b.phone(“555-1234”) }

will generate:

person
nameJim/name
phone555-1234/phone
/person

A simple PHP function lets you do it this way:

$x = XML(‘status’, array(‘code’=1),
array(‘data’, NULL,
array(‘usergroup’, array(‘id’=“usr”))));

A Perl equivalent would be even shorter:

$x = XML(‘status’, [code = 1],
[‘data’, [],
[‘usergroup’, [id = “usr”]]]);

(Note I’m using [] instead of {} because I want the attributes to be ordered.)

No doubt any language with the equivalent of C’s varargs could manage this sort of thing.

(Oh… and if this post is unreadable, blame whoever it was who decided this blog doesn’t need a comment preview button. Dumb, dumb idea.)

I suspect you were being partially sarcastic, but that does help.

No two comment boxes seem to work alike.