I imagine that the title of this document will cause quite a stir in some quarters, but that is quite deliberate. The reason I chose that title is because of similarities with a statement I heard in criticism of the COBOL programming language in the late 1970s. The author of this statement, an advocate of a rival programming language which has since faded into oblivion, claimed that "COBOL is not a structured programming language". Upon closer investigation what he actually meant was that COBOL does not force the programmer into adopting any particular structure, unlike his new favourite. What this most definitely did NOT mean was that it was not possible to write structured programs in COBOL. What it DOES mean is that the developer has to create his own method of structuring his programs, or if he is a member of a team of developers he uses whatever has been set up by the other team members.
This is where the real problem lies because there are numerous ways of structuring and writing your programs in any language, not just COBOL, and most programmers simply do not have what it takes to devise a methodology which produces the best results. They seem to think that simply writing code that works is good enough without taking into account how long it takes to write the code, how long it takes to test it, and how easy it is to maintain afterwards. A good programmer, one who is always seeking to improve his techniques, will have an inquiring mind and will ask himself questions such as:
What a lot of people fail to realise, even today, is that computer programming is not a science, it is an art, and to be successful in any art one must have artistic talent. If a language is flexible and allows the developer to exercise a certain amount of artistic licence then a talented developer can produce a work of art, a well-structured program that achieves its purpose very efficiently and which can be enhanced and maintained very easily, even by others. If, on the other hand, a methodology forces the developer to adopt a particular structure or a particular style, then a talented developer may not be able to exercise any artistic licence and may in fact be constrained by the artificial limitations of the imposed structure. So rather than being limited by his own ability the developer ends up by being limited by the methodology itself.
Using a rigid and inflexible language does not prevent an untalented developer from writing bad programs. Bad programmers will always write bad programs regardless of the programming language which they use. If you give them a set of rules then they will find some way to either misinterpret those rules or to apply them in such a manner so as to defy all sense of logic or reason. So, regardless of the programming language talented programmers will always shine while untalented programmers will always stink.
When I say that a talented programmer will always shine there is one qualification. A talented programmer may be physically prevented from producing work to his usual high standard because of artificial obstacles which are placed in his path. When I say 'artificial' I mean over and above the limitations of the chosen development language itself. It is obstacles such as these which are the subject of this document.
Although UNIFACE may have been designed with rapid application development (RAD) in mind, and although it may have the potential for rapid application development, there is no guarantee that simply by using UNIFACE you will actually achieve application development that is actually rapid. To put it another way, it is not the tool you use, it is the way that you use it that counts. Just as you cannot get the best performance out of a racing car if you do not know how to drive it properly, you cannot get the best out of a performance language if you do not know how to use that language.
In my long career I have used a variety of 2nd, 3rd and 4th generation programming languages, and I have seen implementations which range from efficient to abysmal. There appears to be no end to the ability of some people to think of ways to slow down the development process. Sometimes this is due to the lack of talent in the development staff, while at other times this is due to the creation of barriers or obstacles by others.
I firmly believe that development standards are the sole domain of the development staff, and should only be written once the capabilities and limitations of the chosen development language have been properly investigated. It is only by using the language that you find out what it can do and what it can't do, what it can do easily and what it can do with difficulty. A language may have been designed to do certain things in a certain way, so you need to find out what these ways are so that you can take advantage of them.
It is therefore a step in the wrong direction to have development standards set by non-developers, or to cast the standards in stone before the language has been fully investigated. If you want to get the best out of a language, and I mean any language, not just UNIFACE, then you should adjust your development standards to suit the language, not bend the language to suit your standards.
Too often I have seen development standards which were created for one language automatically carried over to a new one. I have seen new versions of languages being released without any investigation being done on the availability of new and better features. I have seen things done in an inefficient way simply because "we have always done it this way".
In a previous article entitled Development Standards - Limitation or Inspiration? I identified some of the obstacles to good programming that I have encountered in my long career. Among these are:
You would not believe that aspects of database design could possibly have an impact on the development process, but I have encountered several circumstances where this has actually been the case.
One of these areas is the use of technical primary keys, sometimes known as surrogate keys. It is recognised that when choosing a primary key for a database table it is sometimes necessary to add an extra item just for this purpose, something which has no meaning to the user. This is just in case the first idea for a primary key contains data that can actually change over time. What is not recognised, however, is that while surrogate keys may be advantageous in some circumstances there are other circumstances where their use not only gives no advantage but in some cases can actually be a disadvantage. In my humble opinion there are two ways of using surrogate keys - intelligently and indiscriminately. This theme is explored in more detail in Technical Keys - Their Uses and Abuses.
Another example of poor database design which I have encountered more than once is dealing with a history file where an object can have a different set of values depending on the date. I have seen cases where the start date is built into the primary key and cannot be changed, and I have seen cases where several database procedures had to be invoked in order to extract the relevant data for a particular date. When I query these people on their inefficient design I hear the same old reply "but we've always done it this way!" I then tell them that I stopped doing it that way nearly two decades ago when I came across the most flexible and efficient way which I have documented in Keeping a history of changes by date.
I have often come across cases where an application uses a series of control parameters which are stored in the database, and I am still amazed that designers use a single record to hold all these parameter values. In case you are not aware this may present problems in the following areas:
When I first encountered these problems many years ago I immediately sat down and tried to devise a more flexible solution which avoided these problems. The results have been documented in A flexible method of storing control data. When I point out my design to other people a typical response is "we don't have time to work out fancy designs like that", but what they are actually saying is that they just don't have the ability to find a better solution.
Another area which often presents difficulties to the inexperienced is when dealing with many-to-many relationships. Why these people still tie themselves up in knots while trying to find the optimum solution still beats me. The solution which I encountered years ago is documented in How to deal with Many-to-Many Relationships, and I have yet to see a better one.
I am still amazed when I see applications being designed with a small number of large components instead of a large number of small components. Some people seem to think that it is the number of components which defines the size and therefore the budget for a system, whereas in actual fact it is the number of complex components which is the significant factor. I discovered a long time ago that by breaking down a large component into smaller units that I could develop all the small units faster than I could develop the complex whole. I also discovered that these smaller units were much easier to design, much easier to specify, much easier to maintain and much easier to document. My experiences have been documented in Component Design - Large and Complex vs. Small and Simple.
One of the most under-used and under-rated features of UNIFACE is the ability to build components from pre-defined component templates. Unfortunately when UNIFACE 7 was released Compuware did not provide any reasonable working examples so most developers failed to spot the benefits that could be gained by using them. In my case I was already using a home-grown templating system which I had developed in UNIFACE 6, and as soon as UNIFACE 7 was released I could tell straight away that component templates could provide me with significant savings.
The templating system that I developed in UNIFACE 6 started off quite simple, but grew and grew over time. Anybody who has developed a large number of components will soon come across the scenario where they need a new component that looks and feels like an existing component, but with different data. In this situation it is possible to save time by copying the existing component and modifying it for the new data than it is to write the new component from scratch. I have encountered a lot of developers who are familiar with this situation, but I have never encountered any who have implemented a solution that is anywhere near as useful as mine. The simple steps that I took were as follows:
To give you an idea of the savings that can be made from using component templates in 1999 I designed and built a prototype system from scratch that contained 19 tables, 18 relationships and 50 components in 5 weeks. Two similar sized systems that I built previously in UNIFACE 6 both took 12 weeks, so you can see a drastic improvement. Not only did it take less time to build each component, it also took less time to test each component as the code which was inherited from the template had already been tested and debugged.
Another saving that can be made with component templates which I have never seen anybody else use is to do with changes after components have been built. It is not possible to change the structure of a template and have that changed structure automatically inherited by any associated components after a component has been built, nor is it possible to inherit any changes to entity or field triggers. The only changes that can be inherited are the contents of component triggers, so I have deliberately built all my templates with as much generic code as possible defined in component triggers. By taking advantage of this feature I have been able to make changes in the generic code of a template and have those changes incorporated into every associated component simply by recompiling them. This is much faster than the old fashioned method of duplicating each change in every component.
When I tell people that I have 50 component templates in my library they laugh and tell me that they only need 5. I have tried working with their 5 templates and I can safely say that they are sadly mistaken. Creating a component from a primitive template and then having to insert all that extra code to make the component actually work is almost as much effort as building the component from scratch without the use of a template in the first place. One team of developers I talked to actually found their templates so laborious that they preferred not to use them - instead they copied an existing component which already contained the necessary code and changed it to deal with the different entities and fields. In other words they were still using the procedure that I used with UNIFACE 6 and which became obsolete when UNIFACE 7 was released. They have not learned to use these features the way they were meant to be used, they are not achieving the productivity levels with their 5 templates that I can achieve with my 50, yet they persist in laughing at my efforts. I think the joke is on them.
For a more detailed look at the features of component templates take a look at The Power of Component Templates.
People who have been around UNIFACE for a long time will know that it was originally developed around the 2-Tier architecture but has recently been updated to provide features that facilitate the use of the 3-Tier architecture. When UNIFACE 7.2.04 was released it contained the ability to create Object Services as an aid to 3-Tier development, but these proved to be most unsatisfactory as far as I was concerned. It was not until XML streams appeared in 7.2.06 that UNIFACE provided proper support for the 3-Tier architecture.
If you want a brief explanation on the 3-Tier architecture take a look at The 3-Tier Architecture - is it hardware or software?.
I have seen several attempts at implementing the 3-Tier architecture in UNIFACE and each time I had to ask what medication these people were taking because it was quite clearly affecting their ability to design workable and efficient solutions. In the first case the system designers not only insisted on a 3-Tier architecture, they also insisted that it use a separate application model for the presentation layer. On top of that they also wanted it to behave in a more Object Oriented way. Anybody who knows anything about UNIFACE will tell you that it is most definitely not an OOP language, it is CBD (Component Based Development) built around the 3-schema architecture. It should also be obvious to anyone who is not taking the wrong medication that to force a language to behave in a manner which runs contrary to the way it was designed to behave is asking for trouble. These people had a team of 6 developers working for 6 months on their development infrastructure, and when it came to building the first two screens it took another 2 developers a period of 2 weeks. I told them that their approach was all wrong and that these development times were unacceptably large, but they refused to listen. The client however was not willing to throw such huge amounts of money down the drain, so he cancelled the entire project. A description of this failure can be found in UNIFACE and the N-Tier Architecture.
Having seen what a disaster these people created after 3 man-years of effort I decided to see if I could do better. By using the features of UNIFACE in the way they were designed to be used and by sticking to sound design concepts I managed to convert part of my 2-Tier demonstration system into 3-Tier in just 2 weeks. I documented my results in 3 Tiers, 2 Models, and XML Streams. I have subsequently converted the whole of my demonstration system (with 150+ components) from 2-Tier to 3-Tier using the same techniques. Both versions of this system can be downloaded from my Building Blocks page.
Recently I came across another version of the 3-Tier architecture and again I was astounded at the poor implementation. This prompted me to write another article called How not to implement the 3 Tier architecture in UNIFACE in which I documented the following points:
In recent years I have noticed that more and more companies are finding that the ability of UNIFACE to provide a cost-effective internet solution is being questioned, and more and more companies are moving to alternative technologies, such as Java. Compuware are aiding this move by building into UNIFACE the ability to communicate with components which are written in other languages as well as trying to jump on the Java bandwagon with their OptimalJ product.
If these people who are contemplating a move to Java for an internet solution bothered to do their homework they would realise that the Java community is moving away from the idea of generating HTML code from within a Java component and using XSL Transformations instead. This is the basis of the Cocoon Project from the Apache Software Foundation. If these people then looked into UNIFACE they would see that version 8 already has the ability to create XML files and also has access to the Xalan XSLT processor from the aforementioned Apache Software Foundation in the form of the USYSXSLT component. So my question of the day is this - why are these people bothering to link to a Java component to perform an XSL transformation when the same transformation can be done directly from within UNIFACE? If you are not aware of this capability then please read Using XSL and XML to generate dynamic web pages from UNIFACE.
I hope this article has opened your mind to the fact that just because you are using a language that is capable of providing rapid application development that incorrect usage will erase all trace of the word "rapid" and replace it with "retarded" instead. Although UNIFACE has features which are especially geared towards providing rapid development all this potential is totally wasted if you do not learn how to use those features efficiently and effectively. While some developers like myself strive to take advantage of every feature that is available in the language and construct a development strategy that utilises them to the full, others seem hell bent on constructing obstacles and barriers that do nothing but slow the developer down and cancel out any time that could be saved.
You may think that each of these areas of inefficiency that I have highlighted cannot possibly make that much of a difference, but have you stopped to think of what the effect would be if everything you did was the least efficient method? Not too long ago I visited a company whose advertising blurb claimed that they were "innovators" in the field of UNIFACE development. After investigating their development environment I made a list of all the areas where they had chosen the least efficient method. This list ran to 17 pages and 9000 words. I demonstrated to them that I could create software 10 times faster using my methods than they could with theirs. Yes, I said 10 times faster, not 10% faster.
So how many of these inefficient methods are you using in your organisation? Is your application development really rapid, or do you just assume it is?
20th June 2003