Showing posts for tag "abstraction"

Be a Better Programmer, Part 4

Thu Aug 14 09:44:26 EDT 2014

Tags: abstraction
  1. Be a Better Programmer, Part 1
  2. Be a Better Programmer, Part 2
  3. Be a Better Programmer, Part 3
  4. Be a Better Programmer, Part 4
  5. Be a Better Programmer, Part 5

This topic isn't, strictly speaking, in the same vein as the rest of this series; instead, it's more of a meandering "case study" sort of thing. But it has something of a unifying theme, if you'll bear with me:

Be Mindful of Your Layer of Abstraction

Basically everything about computers has to do with layers of abstraction, but what I have in mind at the moment is how it interacts with web programming. First, I'll dive into a bit of background.

The original premise of HTML was that it was an SGML-like markup language designed for representing textual documents, particularly academic ones. Thus, the early versions built up a bevy of elements for representing structured tabular data, abbreviations, block quotations, definition lists, ordered and unordered lists, and so forth. The ideal HTML document would be structurally sound, with each element meaning something that both a human and computer could understand and, presumably, format and put into a textbook.

However, since actual humans don't spend all their time writing academic papers and instead wanted to make layouts and colors and fonts, the HTML they put out wasn't beautifully structured - instead, tables went from representing tabular data to being used for layout, filled with little 1px-by-1px transparent GIFs and other semantically-meaningless crap.

Enter the Web Standards Project, which primarily advocated the use of cleaner (X)HTML and CSS. Among the goals of this advocacy was a desire to see cleaner, more meaningful markup again. This was phenomenally successful and, as browsers improved their support of CSS (grudgingly, in some cases), the miasma of nested tables, font tags, and other meaningless markup receded.

But then we get to today. Though modern HTML markup bears the trappings of "semantic" standards, the essence of it is hardly better than the old way (h/t David Leedy). The proliferation of framework-geared markup is a reflection of the fact that, even with the best of intentions, sticking to strictly meaningful markup is essentially impractical for an "app"-type web site (as opposed to a collection of documents). When you get into the HTML that various JavaScript tools generate at runtime, things just completely fly out the window. HTML5's new elements help a little, but don't solve the problem - is a dashboard page containing a grid of widgets really better represented by <article>s and <section>s than by <div>s? The equillibrium that "best practice" has reached now is that it's more or less okay to have a bunch of nonsense <div>s mucking up the works as long as you try to do a best match for actual content tags and throw in some nods to accessibility/inclusion.

So that brings me to my current views on how to structure the markup of web apps. I used to care a great deal, back when I wrote in PHP - since every tag on the page was something I wrote, either hard-coded or in HTML-generation code, I wanted to make sure that the result was pristine and would work properly even with CSS and JavaScript turned off. My early XPages attempts tried to continue with this, but it's not realistic. While you can (and should) still keep an eye on not spitting out too much HTML unnecessarily, there's no getting around the fact that your page is going to have more <div>s and <span>s than you'd like.

Over the past year, my view has shifted instead to the notion that the resultant HTML+CSS is basically compiled output - or, more accurately, is equivalent to the actual pixels and widgets pushed to the screen when you run a desktop app. In a desktop app, you write to the UI frameworks of the platform and then the frameworks do what they need to do to render the window - sometimes they'll use a different user-specified font, sometimes it'll be larger or smaller, sometimes it'll be high-contrast, etc.. Similarly, my view of an XPage's HTML is that my job is to make the XSP code as clean and declarative as possible and then it's the server's job to decide how that's supposed to be represented in HTML. The ideal XPage wouldn't contain a single nod to the fact that it's going to eventually be output as HTML.

This point of view has come alongside (or because of) my getting religion on custom renderers. Now that my best-case development strategy revolves around renderers, it feels wildly inappropriate to include any references to HTML or CSS classes inside XSP markup (or even themeIds to indirectly reference Bootstrap layout concerns). All that stuff should be determined by the framework at runtime (by way of the renderers and component-generation code), and the XSP should focus on defining the grouping and ordering of the primary components of the page.

But the trouble is that all these abstractions - from pseudo-semantic HTML, through the CSS framework, through the XSP markup - are terribly leaky. No matter how clean I try to make my XSP, there's no getting around the fact that a well-crafted layout needs some knowledge of, say, Bootstrap's column-layout model, or that I want all the containers referencing Task properties to be red instead of the default color scheme. And no matter how clever the UI framework is with its CSS trickery, at some point you're going to have to put in some extra layers of <div>s to get the right sort of alignment (or, worse, include a set of empty <div>s just to get that hamburger icon). And who even knows how you're supposed to feel about abstraction once you start using JavaScript frameworks that generate the entire page - or go even further? Those tend to lead to clean data feeds, so that's good, but phew.

So it's all rules of thumb! The best tack I've found is to pick a layer of abstraction that makes sense with my mental model - standard XSP components + renderers in this case, but it applies to other areas - but to still know about the lower layers, because you're going to have to dive into them sooner or later. That's not, strictly speaking, practical - the XSP framework itself is built on so many other interlocking parts that it's effectively impossible to master every layer (XSP, HTML+CSS+JS, JSF, JSP's leftovers, Java servlets, OSGi, Java, the Domino API, Domino-the-platform, the OS itself, and so forth). But you can know enough generally, and taking the time to do so is crucial.

In short: the whole thing is a mess, so just try to keep your head clear and your code clean.