PreviousNext…

Domino anti-patterns

OK, so here’s something a little controversial. We all like to read articles about best practice, doing things the “correct” way, and so on. How about some stuff on the bad ideas, the so-called anti-patterns that exist? Or is that an overly-negative endeavour do you think? I dunno. But I’m going to kick this off anyway, with some gems from the Notes world… Feel free to chip in!

First off, a view, with an action bar button in it. This button is labelled “Create blah blah document…”, and naturally enough one would expect that it performs some kind of @Command([Compose]) call. Not so! Check this out:

    @Prompt([OK]; "New Document";
    "Please use the button on the main navigator to create a new blah blah document");
    @PostedCommand([FileCloseWindow])

Urgh. Almost as bad as the Querysave form traps that prevent the use of CTRL-S or similar, in favour of pressing an action bar button.

OK, next. Querypaste events in every single view of a database, denying document pastes. Plus, just for good measure, an agent that removes any documents pasted-in. Now, there may be a good reason for this in the odd application, but in every single database you ever created? Sorry, no.

Next! This guy was just kidding himself:

    TheEnd:
        Msgbox "Process completed. Error count was 0"

OK. So what’s this next bit for then?

    lblErrs:
        intErrCount = intErrCount + 1
        Resume TheEnd

Gah. On to the last one for today (these are all real examples, and better still, all feature in the same application).

An agent designed to export a 60+ column view. This is done by concatenating a load of strings to make up the “header” of the export text file. These strings all correspond to the view column titles, and are delimited by a tilde. Cue one entirely senseless bit of code already — NotesView.Columns() anyone?

Then, the code walks the view, and for each NotesDocument, extracts a value from the ColumnValues property and appends it to this gigantic string. Meh. Here’s an extract:

    data1$ = Doc.Columnvalues(2) + "~"
    data2$ = data1$ + Doc.Columnvalues(3) + "~"
    data3$ = data2$ + Doc.Columnvalues(4) + "~"
    …
    data68$ = data67$ + Doc.Columnvalues(69) + "~"

What do you reckon on that? The export takes over an hour in this database (there are around 15,000 documents in the view), and the end-result still has to be manually imported into one’s reporting package of choice (MS Excel). How would you go about addressing this? For a start, why not use COM? Go straight to Excel. The Lotusscript agent isn’t readily portable, and does not lend itself to tweaks. It skims NotesDocument objects instead of using the far more efficient NotesViewEntry class. The string concatenation is an abomination, the resulting export file is horrible, and the code itself, when printed, takes up four sheets of A4. It also crashes my Notes client spectacularly nine times out of ten. First time I’ve seen a RBOD in Notes 6.5! Oh yes, the database contains at least three implementations of this anti-pattern, each fundamentally the same, just tailored for their respective views. Code re-use anyone?!?

Bring on your tales…

Comments

  1. I don't think this is too pessimistic, although many anti-patterns are probably not Domino specific.

    I think you've hit on an important one, though: messing with standard Domino UI features like save shortcuts, action buttons or copy/paste. Applications that force their own UI conventions without huge gains in usability or safety are a real pain.Nik Shenoy#
  2. Ben - the application you refer to is bright pink and green and written by someone with the initials 'R. S.', is it?Anonymolloyous#
  3. Nope :-)

    (Cunning pseudonym BTW badger!)Ben Poole#
  4. The code even uses the plus (+) operator to concatenate strings. I bet the variables arent even declared. Ohh the horror.

    My usual reponse to this kind of code is a quick re-write and loud grumblings about people learning about functional programming. Some day someone will listen and I'll be out of a job.

    ;)John Marshall#
  5. hey wait a minute, i think i wrote that app!

    boy, some people are just mean!

    ;-)jonvon#
  6. LOL! I re-wrote the agent ;-)Ben Poole#
  7. My personal best: I came across a linked-in Sendkeys library on QueryClose which sent an 'n' to the 'Do you want to save this document?' prompt :-)

    Admittedly the chap wasn't really a Notes developer and knew very little about the object model and properties. I'fact, I thought it was rather an ingenious solution. I can only imagine him thinking 'Notes is so crap. I wish there was a way to just tell the document not to save itself.'Colin Pretorius#
  8. "4 pages of A4"

    Thats nothing Ben. I once had to rationalise another "developers" lotusscript which was 60 pages of A4. The script was intended to do something involving appointments and calendars but instead of writing functions and subs the developer had copied and pasted their orginal code and changed just changed a couple of variables each time, such as the day. It was so big that they had had to take all the comments out because it would no longer save.

    Just one long big if statement….urghhhh!Ed#
  9. OUCH! 60 pages? Jeez.

    With my example, I picked on this code being that long because what it does is so … simple. There‚Äôs just no need for that kind of nonsense.

    As for your example Colin, oh that was beautiful :-D Ben Poole#
  10. #1 - Applications that force their own UI conventions without huge gains in usability or safety are a real pain.

    Sounds like Notes to me :)

    With regards to the topic, i'd be interested to see the shonky code I wrote when I was first learning Notes compared to the shonky code i'm writing now. Unfortunately that was at another company and i've since misplaced my "backups".Marcin#
  11. 60 pages? I bet his/her manager believes in high productivity. Just look at how many LOC this developer cranks out a day. ;-)Volker Weber#
  12. Forgot to say on my comment - the 60 pages were reduced to 3.

    Put's into perspective how bad the orginal was.

    Volker, I think the manager must have been impressed with that mammoth piece of scripting because the 'developer' went one rung up the career ladder and became a senior developer. Maybe there's non technical benifts to be had from writing bad apps.

    Ed#
  13. Peter Principle: Some people rise to their level of incompetence in an organisation.

    My Principle: Some don't stop there…
    Colin Pretorius#
  14. I've a comment on the use of NotesViewEntry class. In at least up to release R5.9 this was at best unstable in its use and I had to re-engineer multiple applications because of this "bug". Since then I've not used it but instead used the view object, this was 100% functional although marginaly slower then the viewentryclass.

    My advise would be to test it try it and optimise your codedesign so that when the bug reveals itself again in R6 you can easily re-engineer it to support the handling with the viewobject, YEH for Notes :-)

    Edwin Lucke#
  15. Agreed; I used to code in 5.0.5 and 5.0.8 and they were both nasty in that regard. 5.0.11 and 6.5 are OK so far though.Ben Poole#
  16. That off-by-one bug was nasty, and it's frightening that it stuck around for so long. The worst part is you can imagine that it was a simple array manipulation error in the API code, that was probably fixed with a one-line tweak.

    (Says he, the expert ;-).

    Kinda makes one wish something like Notes were *koff* open-source *koff*, don't it?Colin Pretorius#
  17. OK, so this onversation is almost dead, nobody's reading it, and I can now make a small confession:

    I once wrote a LotusScript agent that was four or six pages long, and didn't use functions at all. Code re-use? Bah! Nope, this thing just turndled through a MASSIVE loop, applying all sorts of criteria to the documents it was handling.

    In my defence, I was going to tidy it up and export all the re-usable bits into functions once it actually worked. The app was a grou-calendar affair - it aggregated everyone's calendar by trawling them all and copying the documents into a database. It didn't copy anything that already existed, but would copy updated (edited) documents since its last trawl. It also had to remove any old documents (appointments 7 days in the past or older) - unless they were repeating documents. This was in the R4.6 days, and if you remember how it handled repeating documents you can guess where most of the kludges were^W^Wwork was happening in this app!

    As say I was going to tidy it up. I demoed it to a salesman in the company. He kept a copy of the demo, and showed it to a customer. Well, actually, he sold it to the customer. So, after a mere five days of existence this app had been sold.
    I kludged it working, then went to install it. To be honest, that was the day on which I decided development wasn't for me - my perfectionist tendancies would stop me from ever shipping anything!

    (I'd developed intranet-style apps there before, and done other development work at a previous company. Some were even sold. But none were sold so quickly, or in such a shocking state when sold.)

    I'm now happily stuck on the Admin track, with occasional dabbles in development. Just for fun, you understand… ;)

    To be fair, we used this app internally at our company as well. It trundled on reasonably reliably until R5 came out. R5 had a group calendar function - not one as easy to use as mine, because it was some wierd embedded Java app - but one that worked well enough. And R5 also changed the repeating events handling, so it broke my app anyway. That combination sounded the death knell for my app, and I was a very happy man! ;)
    Philip Storry#
  18. Use roles to take away access instead of granting it, then list people individually in the ACL to take away roles.Chris King#

Comments on this post are now closed.

About

I’m a developer / general IT wrangler, specialising in (often mobile-friendly) web apps using things like node.js, Java, C#, PHP, HTML5, etc.

Best described as a simpleton, but kindly. Read more…