It is very unusual for a project, whether it be a computer project, an engineering project, or any other kind of project, to be implemented entirely without incident.
There now follows a brief history of some of the projects I have encountered which I class as being disasters.
My company's involvement in this project was limited to the first phase, which was successful. We provided some new COBOL programs which interfaced with the client's accounting package. This particular client had its own in-house staff who were just beginning to build new software using a more modern 4th Generation Language (4GL).
They did not have any problem in using this 4GL until the Managing Director, for entirely political reasons, decided that the entire system be converted from COBOL to this 4GL. He just wanted to boast that his entire system was written in a 'new-fangled' language. The fly in the ointment turned out to be the communication between their software and the accounting package. This particular accounting package was written entirely in COBOL, and the way to update it from an external system was to use a set of COBOL subroutines which were supplied with the package.
The problem arose because this 4GL came in 3 parts - a batch reporting module, a batch updating module, and an online module which could read and update the database. Unfortunately only the batch updating module had the capability to communicate with COBOL subroutines, and this was needed in the online programs. The in-house developers could not provide a solution, we told them it was a waste of time trying, so they contacted the authors of the 4GL. They cobbled together a method whereby the online module could invoke an instance of the batch updating module in order to communicate with the COBOL subroutines. Problem solved - or so they thought!
Unfortunately there was one bijoux problemette - the time that it took this combination of software to run. All the online components ran in one process, but a separate process had to be created for the batch processing module each time they wanted to update the accounting package. This process had to open both the application and accounting databases, perform the update, then close both databases before terminating. In the COBOL application all components ran as subprograms within a single process and could therefore share the same database communication areas. This meant that the databases were opened only once per session instead of once per update. Calling the subroutine to update the accounting package was handled within the same process and did not require the creation of a separate process.
The time that it took to perform each online update was so long that it became impossible to complete a day's work in a single day. The response times got so slow that disgruntled customers took their business elsewhere, which led to the company's ultimate collapse. All because a person who was not qualified made a disastrous technical decision just to satisfy a whim. Administrators should stick to administration and leave technical decisions to technicians.
This was a project implemented in UNIFACE 5 on CHUI terminals. It started off as a joint venture between in-house personnel and external contractors. They spent a lot of time analysing the requirements, designing the solution and writing the development standards, but when it came to writing the actual code they hit a stumbling block - they couldn't do it! Someone had made the decision to use UNIFACE as the development tool, but none of the in-house staff and very few of the contractors had any direct experience of using it. They asked Compuware for help, and they put them in touch with the company I worked for at the time, a software house with a team of experienced UNIFACE developers.
The project manager visited us to discuss a few small programs that he wanted to try us out on, just to see how good we were. As soon as I saw the development standards my heart sank. I could see straight away that they were written by someone who had absolutely no knowledge of how UNIFACE worked and therefore would be difficult to implement. He thought they were the best standards that he had ever seen - I had to bite my lip to prevent myself from saying that they were the WORST that I had ever seen. The terminology was typical bureaucrat - lots of fancy words but the meaning was obscure. There were numerous times in the coming months when we had to ask for plain English translations. When we were shown the database design we could see that it was done by someone who had read a little of the theory (probably off the back of a packet of corn flakes) but had never actually put any of it into practice.
A prime example of this was concerned with occurrence counting. Wherever multiple occurrences were possible we had to display the values 'N1 of N2', where 'N1' was the number of the current occurrence ($CUROCC
) while 'N2' was the total number of occurrences ($HITS
). After a great deal of persuasion we got them to agree to use $CURHITS
instead of $HITS
because of the performance implications. This is where Silly Idea #1 appeared. When the users were told that the value of $CURHITS
would be negative if a stepped hitlist was in operation they said, "Negative numbers are not intuitive. We want positive numbers instead." So instead of '1 of -10' they wanted to see '1 of +10'. When they saw the first screens that were written they immediately came up with Silly Idea #2. It is a 'feature' of UNIFACE that when no occurrences have been retrieved the first occurrence is still painted, but as an empty occurrence with the counters '1 of 0' being displayed. They did not like this idea. What they wanted was for an empty occurrence to be shown as '0 of 0', which would change to '1 of 1' as soon as the first field was changed. This meant putting code in the <start mod.> trigger of every field on that occurrence. The end result was a mass of additional code whose only purpose was cosmetic, thus adding to the cost and complexity of each form without adding one ounce of functionality.
The first batch of programs were for simple lookup tables. They should have been a walk in the park, but it was not to be. We had great difficulty in understanding their program specifications because they were not written in a structured manner, at least not to any structure that was known to us. Instead of identifying explicitly what the program was supposed to be doing or how it was supposed to behave each specification was littered with references to different sections of the development standards. We had great difficulty in pulling all the pieces together only to discover that in some cases some logic was missing, and in other cases the logic was contradictory.
Then there was the sequence in which we were asked to produce these forms. Call me old-fashioned if you like, but I think the natural sequence of events is to write the input forms before you do the update, enquire and delete forms. Not this crowd. They insisted that we do the popup/picklist forms first. So not only did we not have any data to work with, we also did not have any of the forms from which the popups were supposed to be activated.
Then we had problems with the test plans. They wanted the most comprehensive test plans I have ever encountered in my entire career, but they were unable to provide us with any examples. We spent a lot of time in sending them documents only to be told "This is not what we want, try again!" It took a long time before we produced a format that they found acceptable. It seemed that these people were doing everything in their power to make our jobs as difficult as was possible, and all we could do was grin and bear it.
There were numerous occasions when our developers would hit a problem with their design, but each time we told them "This is causing a problem. We could achieve this more efficiently and effectively if you changed the design" the answer that we received was always the same - "There is nothing wrong with our design. You will just have to code around it." The end result was large volumes of code whose sole purpose was to circumvent flaws in their design, or to satisfy a user's cosmetic fancy.
Then we started to get forms which were more complex, and this is where the genius of their designers really shone! The screen designs began to get bigger and bigger. If the typical monitor at that time could display 20 lines of data, these people were specifying screens that were 40, 50 and even 80 lines deep. We immediately held up our hands in horror and said "This is not the right way" but we were told "This is what the users want, and you can't argue with the users". We tried to tell them all the reasons why such large screens were not a good idea, but every argument fell on deaf ears.
It seems that the logic behind this decision was based on the users' experience of a previous system where the screen sizes were small but the navigation from one screen to another was rather cumbersome. In order to avoid the problems of branching to another screen to see additional details, and then to jump back again, they decided to have as much detail as possible built into a single screen. So instead of having to branch and return with other forms they felt it would be much easier to scroll down and then scroll back up again.
I don't know if any of you have ever worked with very large forms, but here is a brief list of some of the problems that may arise:
During the user testing phase the complaints started to trickle in. These complaints grew when they saw a similar system which was built for another section, but which had smaller screens and therefore ran faster. It also had buttons so that you could quickly navigate to a new screen of associated details, and then return to the original screen in the blink of an eye.
The end result of our months effort was a system that we developers considered to be a technical failure, and none of us were proud to have that project appearing on our CV's. Because of the poor design and poor development standards it took longer to develop than it should have, and, worst of all, the users were not happy with it. It was slow, it was cumbersome, it was months behind schedule, and required expensive amounts of additional hardware before it would run at anything near acceptable speeds.. It may not have been what they wanted, but by God it was what they asked for!
At first they tried to blame us for the poor performance of the system. They tried to insist that their design was perfect and that it was our implementation that was at fault. We got them to engage the services of a Compuware consultant to review the project, and his opinion (which was expressed in terms that were much more polite than the ones I would have used) was that all performance problems stemmed from the design and that nothing could be done within the code to make any significant improvements. They then changed tactics and decided that perhaps UNIFACE was the wrong development tool, but that argument was shot down in flames when they saw a similar system written in UNIFACE that was designed using much smaller forms and therefore did not have the performance problems inherent in their design.
This was another project that was doomed to disaster before the first line of code was written. Decisions were made up front which caused the eventual implementation to become more and more difficult.
The development language was UNIFACE 7.2.05, which unfortunately was not the best tool for web development at that time. The only provision it had for supporting the 3-Tier architecture was with Object Services. However, these were not used because they did not support a separate application model for the presentation layer, and they were not stateless as is required in a web application. This meant that they had to devise their own method of providing these two requirements, then develop the code to support it.
The development team consisted of in-house people as business analysts, and external contractors as the analysts, designers and developers. The external contractors were made up of permanent employees of outside consultancies (including some graduate trainees), some consultants from Compuware and some freelance contractors. None of the Compuware consultants had worked on a web project, none of the contractors had worked on UNIFACE 7 (although some had worked on UNIFACE 6), and the graduate trainees had no experience of anything.
The architecture which they devised was based upon the principle of passing associative lists (arrays) between the different components. List processing is a very powerful feature of UNIFACE which I have used quite extensively, so I can vouch for its effectiveness. However, there were some features of their design which proved to be unnecessary complications. One was the insistence that every database table have a technical primary key obtained from its own number sequence. A second was that every primary key be named 'ID'. These might not appear to cause any problems to the uninitiated, but an experienced developer will instantly recognise the potential difficulties:
read u_where (ID=123)
because the field named ID has a different context here. The name ID must therefore be converted into another name before it can be used in the read
statement. If the entity contains several foreign keys then the conversion routine becomes more complicated as the number of possible names is increased. It is necessary to know the name of the parent form so that the name 'ID' can be converted correctly. All this complication is totally unnecessary in my standards because I give each primary key a unique name which identifies its context, therefore it can be used as a foreign key without having to be converted.Another problem with their architecture was the number of components. These people had read about design patterns, so had decided that each function should be handled by a separate type of component, one for each pattern. They ended up with a system that had 10 layers - web pages, controllers, decorators, business objects, business component interfaces, business service bridges, views, translators, data caches and data services. In the first place it was rather cumbersome to create a working use case with this number of components, and in the second place testing and debugging was a nightmare because a fault could be anywhere within those 10 layers. Quite often a use case that was working one day would fail the next day because someone had made a change to one of those components, and it was a very long-winded process to step through all 10 layers of components trying to find and fix the cause of the problem. Particular problems were caused by the user requirement for a separate data snapshot at each stage of the use case so that the values at each stage could be reinstated at any time.
The development people were broken down into separate teams such as business analysts, database designers, component architects, screen designers, and so on. Most of these people had never actually done any UNIFACE development, so they did not know how easy or difficult it was to implement their designs. They were also too arrogant to take advice from people they looked down on as 'mere coders'. The screen designers in particular used an expensive tool that produced beautiful designs, but which were a pig to implement. In particular they loved to paint data fields anywhere they liked on the screen even though it created problems with overlapping frames, but they didn't care. The database people used a data modeling tool where the concept of subtypes was totally different from that used within UNIFACE, and therefore caused untold amounts of confusion. For some reason the contents of the data modeling tool had to be exported in word processor format before it could be viewed by us developers. These documents were filled with business names for all the fields and entities, but these names were usually too large for the physical database and so had to be converted before being input into the UNIFACE repository. The program specifications were filled with the output from all these different design tools, and you would not believe how difficult they were to work with. They appeared to be just thrown together without any thought about structure. One particular specification I was given did not identify the physical entity and field names I was supposed to work with. It simply referred to another document, but that document had not been written yet. I have never in my entire life had to spend 3 days deciphering the specification for a program for which I would normally expect to produce the code in an hour.
Some of the senior consultants had programming backgrounds which were rooted in the 'C' and 'C++' languages rather than UNIFACE, and they insisted that Object Oriented (OO) techniques be used in the coding. You should be aware that UNIFACE is not an OO language, therefore trying to force it to behave in that way is simply asking for trouble. I distinctly remember that the error processing that they devised was more cumbersome than anything I had ever encountered, and what is worse it contained an unstructured GOTO
statement!
I was not impressed with their ideas regarding use case design and code re-use. In my methodology I have a single screen which lists occurrences of an object, and on this screen I have a separate button for each child screen that can display different details related to that object. (refer to UNIFACE Development Guidelines - Part 3 (Component Templates) - List Forms for more details) The user simply selects one of the occurrences in the list screen, then presses one of the buttons to go to the desired child screen. But not these cowboys! They decreed that buttons were no longer fashionable and that the child screen had to be activated simply by clicking on an occurrence (i.e. a hyperlink). As each hyperlink had to be hard coded within the list screen it meant that they needed a separate copy of the list screen for each child screen. So instead of a single list screen serving a number of child screens there were a separate list screen for each child. Is that what you call an efficient design?
My involvement in this project was less than had been suggested at my interview. I had been head hunted specifically for this project because of my knowledge and experience of UNIFACE in general, and of version 7 in particular. Not only had I designed and built several systems in UNIFACE, but I had also created a development infrastructure with common procedures and standard templates which enabled me to build applications very quickly. I had successfully converted this development infrastructure from UNIFACE 6 to UNIFACE 7 so that I could make full use of all the new features in UNIFACE 7. I was told that my level of knowledge and experience was very rare and would be of great benefit to this project, but when I arrived they totally ignored anything I had to say because it did not fit in with their philosophies. My methodology did not use all the buzzwords that were fashionable at the time, therefore was not deemed to be 'politically correct'.
They had a team of 6 people who spent 6 months prototyping the development infrastructure, and when it came to building the first use case, a simple Selection screen and a List screen, it took 6 developers a total of 2 weeks before they got it right. With a bit of practice they got this down to 2 weeks with a single developer, but I was not impressed. At a project review meeting they all stood up in turn and praised their wonderful architecture. They dismissed the long development times as mere teething troubles that were to be expected with new and revolutionary ideas, and that their techniques were definitely the way to go in the future. They were most upset when I stood up and told them that any architecture that took weeks to build a component instead of hours, as I was used to achieving in my own architecture, was grossly inefficient and was doomed to failure. This statement may not have been very popular, but it turned out to be prophetic.
After completing a few more use cases the project manager re-calculated the project plan by replacing the expected development times with the actual development times encountered so far. The result seemed typical for a government contract - only £2 million over budget and 6 months over schedule. When this was explained to the customer he put the entire project on hold before deciding what to do next. Ways were sought to bring down the development times to acceptable levels, and I was eventually asked to demonstrate what I could do with my own environment. Somebody else had to do the development, and I was only allowed 30 minutes to train them in my techniques, but one particular developer went off and rebuilt a use case that had taken him 10 days using their architecture and brought it down to 10 hours using mine. But even this massive reduction did not impress them as my methodology did not use the "fashionable" techniques that they favoured so much.
At this time UNIFACE version 7.2.06 was released, and when I read the release notes regarding the new commands for dealing with XML streams and the improved support for the 3 tier architecture I knew straight away that this was a far superior method of providing what they wanted. But would they listen to me? Not a chance! To cut a long story short the project was cancelled and I was sent back to the Woking office to await re-assignment. While there I got hold of a copy of 7.2.06 and modified part of my development environment to see how easy it was to build software using the 3-tier architecture and a separate application model for the presentation layer. Within 2 weeks I had successfully produced a Select/List screen, and Add screen, a Modify screen, an Enquire screen and a Delete screen. Were they impressed? Not a chance! So I posted my findings on my website (refer to 3 Tiers, 2 Models, and XML Streams for more details), then quit to join another company.
This disaster is documented more in UNIFACE and the N-Tier Architecture.
This is not actually a case where a project went bad, but where my involvement in a project was terminated due to what I can only describe as a "brain fart" by the client.
In December 2011 I saw an advert on one of the internet job sites asking for a PHP contractor with experience of web services. I applied for the job and was subsequently contacted by the recruitment consultant who supplied me with specific details regarding the project:
The recruitment consultant went to great pains to ensure that this project was within my capabilities as the first contractor he sent for an interview with the client quickly realised that the job requirements were outside his skill set as soon as the interviewer began explaining them to him. It would appear that the original requirement from this client just asked for a "PHP contractor" without going into specific details. I assured him that I had actual experience in each of those areas:
The recruitment consultant subsequently contacted me to say that he had set up an interview with the client, the Richmond Group in Bournemouth, for later that week. I was interviewed by Darren Cheeseright, and he went through the project requirements while I explained my experience in each of those areas. He told me that while load balancing of both the application and database servers was to be part of the overall project, that part was to be handled by someone else. He asked me if I had experience with SVN, to which I replied in the affirmative. I asked him the following questions:
Q: Why are you migrating from Linux to Windows?
A: Because we are finding it difficult to find developers with Linux experience.
Q: Why do you use stored procedures instead of dynamic SQL?
A: I don't know why, it's just the way it has always been done.
Q: Why are you using the SQL Server driver indirectly through PDO instead of directly?
A: I don't know. It was something that was recommended to us.
While talking about the use of stored procedures Darren explained that they were written and maintained by their own DBA and all that I had to do was call the relevant procedure. I explained that while I had used stored procedures in the past in all my recent projects I used nothing but dynamic SQL. The so-called speed benefits of stored procedures were no longer evident in modern computer systems, while in my experience dynamic SQL was easier to write, easier to deploy and easier to debug. Darren said that some other projects which used .NET were moving away from stored procedures, but he couldn't explain the rationale for that decision.
As far as I was concerned I was a perfect match for their requirements, and this was confirmed shortly afterwards when the recruitment consultant phoned me to say that I had got the job and how soon could I start? We agreed on the following Monday, so on December 12th at 9am I arrived at the Richmond Group's offices in Bournemouth. The sequence of events was follows:
It was during my evening meal that I got a phone call from the recruitment consultant telling me that the people at Richmond Group had decided that they no longer wanted my services and that I had been removed from the project. I could not understand the reason for such a decision. They could not claim that the work was beyond my capabilities as, after only two days into the project, I had not actually done any work at all. All my time so far had been spent in admin tasks and setting up the development environments on the two servers, something which was not specified as being part of my responsibilities and which they should have done themselves. They could not claim that the work, the changing of database extension plus the introduction of web services, was beyond my capabilities for the simple reason that I have already carried out similar work on other projects, and the code is available for download from my RADICORE website. If they fired me because of my lack of experience with Linux or IIS then I should point out that those skills were never identified in the contract, nor were they mentioned as requirements in the interview. The amount of Linux and IIS work to set up the development environments for this project could have been completed by one of their own employees in no more than 30 minutes. The rest of the 3 month contract would have been devoted to the PHP work, and it was the PHP work, and *ONLY* the PHP work, which I was hired to complete.
I consider my treatment by the Richmond Group, especially the fact that they fired me without discussing their concerns with me beforehand, and refusing to discuss them with me even afterwards, to be totally unprofessional and downright insulting. I would like to single out the following individuals for their personal contributions to this farcical event:
In all my years as a contractor I have *NEVER* been expected to create the development environments myself, and I have *NEVER* been expected to download and install the software that I needed to get the job done. This has *ALWAYS* been done by one of the client's admin staff as only they have the correct privileges to do such things. A contractor should only be given enough privileges to see what he is allowed to see and update what he is allowed to update, and this should exclude the ability to download and install software on multiple PCs.
The notion that they fired me "because they thought I was not capable of completing the project" is absolute b*ll*cks for the simple reason that I had yet to produce a single line of code which supported that theory. I had not yet produced a single line of code for the simple reason that I had to waste my time in setting up the two development environments, something which they should have done themselves but were too ashamed to admit.
In 2006 I was contracted by a design agency to enhance the website for one of their clients by rewriting the administrative part of their application to include Role Based Access Control which was available in my RADICORE framework which I had recently released as open source. This was written as a bespoke application and was a great success. The design agency had a second larger client who wanted something similar, but instead of writing another bespoke application they asked if I could develop it as a package which they could then sell to multiple clients. I agreed, and the TRANSIX application was born. I used Len Silverston's Data Model Resource Book to provide the database schemas, and after starting the development in January 2007 I had a working prototype available in 6 months.
This second website was written as a 2-Tier application where the Business and Data Access layers were combined. When the Presentation layer required any sort of access to the database it called a function to access the old database directly. I replaced the contents of these functions to call RADICORE's database classes in order to access the new database instead of the old one. As my code used a separate Data Access layer this converted the application from 2-Tier to 3-Tier.
As well as converting the original application to use the TRANSIX database I was also asked to add a series of new features, and the switchover to the new application was completed in May 2008. Note that I had kept the original code in the Presentation layer and had simply replaced the code in the Business layer, so the "new" front-end website looked exactly like the "old" one, except for some new facilities. It was only the back-end administrative application which was now completely different. Their website with the new back-end ran happily for several years, and was enhanced several times to include new features. This included separating the front-end website and back-end administrative application so that they ran in separate domains where all communication between the two was done via web services. This again was achieved quite easily as I had developed a technique whereby it only required a simple amendment to each database function. Where a database was read-only, such as PRODUCT and INVENTORY, it accessed a copy on the local server which was synchronised using database replication, but where a database had to be updated, such as PARTY and ORDER, it used web services to perform those updates on the remote back-office server.
In 2013 the client decided that the entire front-end website needed to be enhanced in order to provide a responsive web interface, and as I was only responsible for the back-end administrative application a front-end developer was hired to do this work. Anybody who is familiar with the 3-Tier Architecture and converting a web interface from traditional to responsive (which I did to TRANSIX several years later after it became GM-X) should be able to tell you that this exercise should be strictly limited to the Presentation layer. This front-end developer had obviously not read the memo as he decided that the RADICORE framework was not a "proper" framework, so he decided to rewrite the whole shooting match using his favourite framework, which was Zend. I registered my objection in the strongest terms possible, but I was ignored.
The result was as I expected - a Ducking Fizz-aster (transpose the 'D' and the 'F' to get my real meaning). The project went way over budget, was over a year late, and was so full of bugs due to the failure to replicate the business rules in the existing Business layer that the volume of sales dropped dramatically. The loss of revenue caused them to cut down on staff, and the company owner not only had to stop paying himself, he had to take out a business loan just to stay afloat. I had no sympathy for his plight as he went ahead with the rewrite over my written objections. Relations between us got so bad that he stopped paying my invoices for the service contract, and he decided to cut his losses by stopping all use of the TRANSIX package and replacing it with something cheaper. By some miracle the company is still going, but a stupid mistake by a single front-end developer in trying a full rewrite instead of replacing a single layer nearly caused it to go to the wall.
Tony Marston
10th June, 2002
mailto:Tony@tonymarston.net
mailto:TonyMarston@hotmail.com
http://www.tonymarston.net
2nd Apr 2018 | Added Project #5. |
3rd Mar 2012 | Added Project #4. |