The inspiration to this series of blog entries partially comes from looking at code posted in the developerWorks forums. Some of it is extremely hard to read and understand, even if you ignore the fact that the forum removes indentation from the code.
If you write code that is hard to read, your applications will be hard to maintain. Write the code so it is easy for the poor person who will be maintaining the code in the future. Most probably that person will be you. You might also have to post your code in the developerWorks forum or on StackOverflow for help. If the code is hard to read and understand, you might not get very much help.
What I will talk about is what you can do to become a better programmer, and write code easier to maintain. After being a Notes developer since 1996, I have learned a bit about what makes a Notes application easy to read and to maintain. I want to share some of my thoughts on this blog, or in the words of Kevin Spacey at Lotusphere 2011: “sending the elevator down”. Hopefully it will help someone.
I will not talk to much about basic programming concepts or how to program in Domino Designer. I will assume that the reader already knows that, and is familiar with especially Lotusscript. I will also not talk much about how to create applications with a nice and easy-to-use user interface. That I will save for a later series of articles.
Instead I will focus on things that I think will make you a better Notes programmer. I don’t take credit for coming up with all the ideas I will talk about, some are from attending sessions at Lotusphere in the past, and some were methods I picked up where I work or worked before. Many of the tips are almost defacto standards among Notes/Domino developers.
In this first article, I will start with some tips for when you create forms.
Use field names that makes sense, and don’t use cryptical field names. You may remember right now what kind of data the field is supposed to hold, but in a few months, you have no idea what is stored in it. Some developers use hungarian notation or some similar system with prefixes to indicate what is in a field, but in my experience that makes just for massive confusion later. The only prefixes I use on field names are dsp for any computed-for-display fields and flag for fields that are used to indicate if a document has been processed, is ready to be deleted or to decide if parts of the form should be hidden or not.
If you use field names that indicates what kind of data types they contain, be consistent and at least use proper indicators. It is not a good idea to call a field txt_no1 if it contains a number. Anyone that sees that field name will assume it is a text field, and this will cause errors later on.
Don’t copy fields and keep the automatically generated name. If you make two copies of the field Comment, you will have the fields Comment, Comment_1 and Comment_2. Rename the fields at once, before you save the form. If you save the form, the fields will be added to the UNK list, and will show up in different places, even if you never used them, and they are not present on any forms.
My next suggestion is just something to think about, and it is actually more important when writing Lotusscript code. But since it impacts @Formula language, I am bringing it up together with the forms/fields. My suggestion is to consider using English field names, even if you are not a native English speaker. If you post code on forums like developerWorks — where the majority uses english — people will understand your code and thought process much better when the field names and variables are “self documenting”. However, I can understand that in some companies, you are told to use the native language for fields. In those cases, consider translating your code (field names and variables) before posting it. Test it to make sure you did not introduce any errors during the translation process. But if you can, use English as that is the universal language for programmers.
Hidden Fields and Text
When you hide text or fields on a form, use color coding and fonts to easily spot what is hidden and what’s not. I format everything that is always hidden in red, Arial 8pt. This makes it easy to see if red text is actually visible on the form, for example as an error message. Fields and text that is hidden to the normal user, but visible to certain users (e.g. database administrators), I often make blue.
When it comes to hidden fields, I try to put them all in one section, usually at the top of the form. I do this as they often are used for computed fields further down, or to control hide-when sections of the form, and that is evaluated from the top of the form.
In some places, I have a hidden field, followed by a computed-for-display field. I do this so the field can not be modified by the user, but it is modified by action buttons or other code using the UI classes. In those cases I put the hidden field first, then the computed-for-display field named the same but prefixed with dsp right after..
Below you can see a simple form from one of my production applications.
With just a glance, you know what is hidden and not, and if any fields are display-only. You may wonder why I use computed-for-display fields instead of computed text. That is because if a user would forward a document via email, any computed text will be blanked out, while a computed-for-display field will show the value correctly. You also want to use descriptive labels, or even comments, to explain what the hidden fields are used for.
You can also see that I try to make the hidden fields easy to read. Using tabs makes it very easy to line up the fields and labels. You will find that in the long run, this makes it much easier for you to read and understand your own forms later.
Just as an example, below is another form where the hidden fields are all over the place, different format and some with labels/explanation, some without. Much harder to read, even if this is not an extreme example. Since the fields are logically named and grouped, it can work, but it is not pretty or optimal.
I also use red for hidden columns in views, again to make it obvious what is visible to the user and what is not. Normally I make even hidden columns wide enough to display the content, at least during the design phase.
That is it for forms and views. In my next article, I will look closer at Lotusscript, and how you can make your code there easy to read and maintain.
Hmm … for form we even go a step further and put all those hidden field inside a table and put the table under a section. That way it does not occupy precious screen real estate when you don’t need to see it and when you do you can easily open the section.
I would avoid a table AND the section.
Tables because they can interfere with formatting, and possible use of the form in a dialog.
Section I avoid because the opening of a section counts as a change, causing Designer to ask you if you want to save. I don’t like that.
You could extend @Tinus’s scheme by having a hide when on the section.
I use this with an environmental variable to switch “Debug mode” on and off.
I then have a toggle on the tool bar that allows me to instantly make all of the hidden fields visible – very very useful.
I have often used a section that is hidden based on membership of a role, often called [debug]. I think I like the environment variable idea better as it does not require changes to the ACL, which requires Manager access. Something that, as a developer, you may not have in a production system.
I like it! Some good techniques are popping up all over.
I blogged about it a while ago – It saves me loads of time. http://www.seancull.co.uk/public/seancull.nsf/dx/application-debug-mode.htm
With field names I would also recommend bearing in mind that Domino Designer search is extremely powerful. But only if the values you’re searching for are easy to find. If the field name is used for other purposes elsewhere in the system or on other forms with different purposes, the Domino Designer search will be of little use.
I always use bright pink for hidden stuff on forms, as there’s no way on earth (unlike red, which does have its uses) that would be visible in the UI.
Another tip: just because you’re creating/manipulating items in client-side LotusScript, you don’t have to add them to the form – they’ll still be saved on the underlying document. Having loads of hidden fields on the form that have no code behind them is often pointless (unless you want to put them there in order to document on-form what they’re for).
Pink makes sense. I just got so used at red at my previous job that I continued doing that. But you have a very strong argument there. I use a different font size (8pt, vs normal text at least 9pt), so I can pick it out that way even if the text is red on teh form, but a different color absolutely makes sense.
Yeah, I’m a pinky too Julian, Red is for highlighting errors and suchlike. A section at the top of a form for hidden fields is a favourite of mine as well, though for convenience (to lessen scrolling up and down) sometimes in a long complex form I might use such sections elsewhere near where other fields associated with these hidden fields are located. No need to be absolutely rigid with your techniques.
There are two types of people. Those who like Hungarian Notation. And those who don’t. I am strongly in the don’t camp. It adds to the confusion. Like you, I colourise my hidden fields with red. I also use Display_ before cfd fields. But I also use a few more tricks on my standard Notes forms.
If a line, field or paragraph has hide-when values attached to it, I normally use Blue text to indicate that something is there that you cannot see. I use Green text permanently hidden to “document” why some things are done the way they are for those who are looking at my forms later. The textual version of comments.
For variable names in code I usually end the variable name with the type of object it is. So there are SalesDoc, StockView, CommentRTItem etc. Some people use the object in front, but I always use the end because you can group your objects together for easier lookups with typeahead assist.
But my biggest tip I can give is to suggest that people document the “why” of things. I can see the “how” but that gives no clues as to the thought processes of why you are doing it this way.
One thing I did not mention is that I format any pass-through HTML as Courier 9pt, usually in a dark green color, bit sometimes black. Computed text in pass-through HTMl I make maroon, so it is easy to pick out.
When developing for the web, putting a hidden table before a RichText field will drive you barmy.
The RichText field will behave in unexpected ways. Domino might put in an extra br tag before the RT field or it might not use p tags for formatting content … just to list two most common irritants I’ve come across.
This topic deserves to become a blog or wiki in its own right. How would that be done?
You are right about the advantage of using English even if you are not a native English speaker.
But, too often the usage of plain English names are a problem, particularly when it comes to localization. If you do not like Hungarian or other prefix notation, add just a lowercase letter to all your fields (or any other design element) to avoid the confusion with the actual word, i.e. in your example, Outcome or History will require a DNT tag if using DGW, and will require additional time and efforts, testing and debug. If you just name them fOutcome and fHistory (or txtHistory and txtOutcome if you like it best) the localization process will be much much easier. But also, from my point of view, avoiding the usage of plain words increases the readability of the code and design elements and also for power users creating their own views, foders and agents, this is a perfect way to raise attention to the fields names.
I wonder why the localization process is always forgot within the Domino/Notes arena, when it comes to standardization and best practices.
I see your point, and for translations it makes sense. But I still don’t agree that the code get easier to read if you use cryptic (or even prefixed) variables.
Then we also have the case where your users want to do a seach:
[Status]=”Open” AND [Creator]=”John Smith”
[txtStatus]=”Open” AND [txtCreator]=”John Smith”
It’s not obvious to a regular (or even power) user that the fields need a prefix like that.
Sorry to come back this “late”, but I believe there is still a remarkable point about this.
I don’t question the readability of your example as a chunk of text, but if you see this as the strictly code that it is, a prefix could indicate quickly that this is just code and not the word itself. For the programmer, this is almost useless (if you can read code, you make this distinction quite easily), but for the localization process this is really relevant, and avoids a lot of hours of tests.
Also, from the usability point of view, I guess that the users that could create a private agent or a private view, are really power users, very power users in fact these days, that will not even care if they have to add a prefix to the standard word. Anyway, you will need a sort of reference api manual with the field names, or if you just inspects the field list, having always the same prefix (or using some kind of coding guidelines) it will straightforward to work out the difference between “Income” and “fIncome”. For non native English speakers, could also clearly pin-point that this is a “code” word and not just the word itself.
Not doing this, at the form and coding levels, implies having to go a very hard and time consuming process when you want to localize, that normally resents the quality of the final localized product, or even makes it useless, at least in some functionalities.
The kind of problem that you see right now with the oral interface of Windows Mobile, which was so terrible wrong localized, that it just doesn’t work for many functionalities in Spanish. And the only problem is that the code words and the actual words match, too much. I really believe you must keep the code, code, and the words, words. If you mix them, nothing good comes out.
Correction: it believe is “speech interface” and “oral interface” is just a wrong spanish loandword.