Test Intensive Development in Delphi

Slides from a Birds of a Feather session at BorCon 2001

At the 2002 Borland Conference, I presented a “Birds of a Feather” session on Test Intensive Development in Delphi. A couple of dozen people attended, in spite of the early morning time slot. Most of the attendees were new to test intensive development, though a few were experienced in it and shared useful tips.

My introductory talk and demo was adversely impacted by a technical problem with the projector and missing microphone; hopefully this slightly expanded set of slides will fill in the gaps that caused.

Download TID-Delphi-BOF-Borcon-2002.ppt

A Content Management System

I generally say that reinventing the wheel is not a good idea. Sometime’s it’s an educational experience, though!

KCMS is Kyle’s Content Management System – a working name for the content
management system which “powers” this web site. It is an early work in progress, “version 0.1”
system. I put it together last fall to facilitate updating this site more easily.
It is composed of two parts:

On the web server, a few kilobytes of PHP code extracts content from a database,
applies a template, add in other elements (such as the advertisements), and thus
renders the page.

Unlike many other CMSs, the admin / authoring application is a
Windows application – not a web application.
It is shown here.


First, a login screen. This is logging in to an Interbase server on my machine;
I edit everything here, then push it to the production machine when it’s ready.
Although currently only I am editing content, this system would support multiple
users easily.


I use Internet Explorer as an ActiveX control for the "home". In
a business app, I would display some meaningful data there – some kind of current
snapshot of the problem space. For example, the number of orders placed so far
to day, month-to-date sales, etc. For the CMS I could indicate things like how
many articles need to be uploaded to the server.


The find / list screen is not all that helpful yet – it only filters on two fields (title and
full text), and sorts on one field at a time.


This is the above screen, filtered to articles that mention Delphi in the title.


Here are the details for one article / piece of content. This screen again
uses embedded IE to display a preview of the content. It uses the same style
sheet as the real web site, so the fonts and spacing match.


Right now, the only editing control is straight, un-high-lighted HTML. The
"edit content in DW" button launches DreamWeaver to edit this item
there. I may also provide an ability to launch GVIM or another HTML-aware editor
for syntax highlighting later.

Were this a commercial app, I could get a syntax highlighting component for Delphi
and provide good HTML and passable WYSIWYG. For an internal-use system,
using DreamWeaver works quite well.


The client software can connect to both the local development database and
the production database, and copy all updated data to the production system
on the web site. An alternative solution would be to apply templates and
generate static HTML locally, then FTP it to a non-database-equipped web
host. That would be quite useful for people who don’t want to pay for and support
database-capable web hosting solution.

That’s where I am so far. It’s all quite alpha – certainly many hours of work
would be needed to polish it up. It’s good enough to start using for content
though, so that’s what I did.


Motivation and Observations

Why did I do this, instead of just using FrontPage or DreamWeaver?

  • It’s my mechanism, I can add hooks as needed.
  • The template is stored just once, and applied as needed. This is a nice
    parallel to desirable software engineering practices, since it lets me tell
    the computer about the page layout "once-and-only-once".
  • The content is stored without any template applied. DreamWeaver applied
    each template "statically", so what I updated a template it would
    update every single page on the web site.
  • I can apply more than one template to the same content (i.e., printer-friendly
    version of each page). Because of the above points, I was able to add the
    "printer friendly" feature in less than an hour, and it works on
    every page powered by the CMS.
  • I can query the data, and automatically show the most recent additions on
    the home page, list everything on the listing page, etc.

What about other Content Management Systems?

Frontier / Manila looks quite nice, but I host all of this on a Linux machine.

I looked at a number of "open source" content management systems,
and it seemed like the effort to customize them to do what I wanted could easily
exceed the effort of building this from scratch.

Background on the URLs Used

When looking at some existing CMS systems, one of the things that bothered
me was the URLs they used. For example, I saw that BroadVision uses URLs like
this:

http://www.broadvision.com/OneToOne/SessionMgr/services/services_svp.jsp
?BV_SessionID=NNNN1165913018.1004016458NNNN&BV_EngineID=cccca
dcdgllkkdfcefecefedghhdfjl.0&serviceType=SolutionValueProposition&
channelname=Solution+Value+Proposition&channelRuleset=Services+Channels
&program
Name=Solution+Value+Proposition+Overview&programRule
set=Solution+Value+Proposition+Programs

Fortunately, I cannot afford Broadvision 🙂 . I suppose all of those characters in the URL
cost a lot of money.

With some excellent feedback from the St. Louis Web Developers’ user group
and elsewhere, I ended up with URLs like this:

http://sitename.com/story-NNN-other-text-here.html

The NNN is a number, and the other-text-here is a very short summary of the
page topic / title. These URLs have several advantages:

  • The look "static", so there is no risk of a human or search engine
    confusing them with per-user content (like a shopping cart, etc.)
  • They are short, and can be emailed without wrapping to multiple lines.
  • The CMS can key off of just the NNN part, so as I change page titles, old
    bookmarks will still work.
  • The URLs feel "harmless" to the end user who sees them.
  • There is some indication of the page content in the URL, which is quite
    helpful is a URL somehow becomes separated from its descriptions. I think
    this is superior to the approach used in Frontier Manila or in Vignette, both
    of which only have an identified.
  • It’s trivial to map these URLs to the proper content generation script using
    Apache’s mod_rewrite.

Why PHP?

PHP is ideal for small, simple needs like this. Although I use Java heavily
for enterprise web application development, the effort to install
and support a Java solution would not be justified for this app at this time.
The server part of this software consists of 2-3 PHP files and nearly zero installation
effort. I’ve implemented and personally deployed a number of Java web applications,
and it would still take me a good while longer to get such a solution running
here.

Why a Windows application for the authoring / admin?

Most content management systems use a Web interface for the administration
/ authoring interface. I found that I can build a good interface much more quickly
as a Windows application than as a web application – so why bother? I don’t
have any need at all for widespread, zero-deployment access to the admin interface.
I do have a need to work on the content when not even connected to the Internet.
Therefore, a Windows app was a good solution for my problem.

Comparing PHP and ASP

PHP and ASP (Active Server Pages) have many ideas in common, and I tend to lump both in to the same category: page-based server-side web scripting tools. I use that category for small to medium sized application; I usually don’t choose it for large or complex web applications.

Here are a few points of comparison between the two:

  • PHP is more seamless across platforms. I can develop on my Windows box and deploy on Linux. (I know about ChiliSoft’s ASP implementation for Unix, but I don’t see much point in bringing my ASP code, which tends to use COM objects, over to Linux.)
  • PHP has a great number of functions that a web developer needs “in the box” – read through the manual to see the list. I found that I had to go looking around to third parties and COM objects to get some things in ASP which
    were already there in PHP. For example, the htmlentities() function.
  • PHP is very often available on external web hosts, if they use Unix/Linux servers, at very low cost.
  • ASP is not tied to one language. It uses the same infrastructure to work with VBScript, JScript, PerlScript, PyhonScript, and more! This is an excellent approach, and Microsoft should be applauded for it.
  • In ASP, the dominant model for DB access is to use ADO, which provides a degree of database independence; PHP has seperate functions for each database type, and requires an additional layer to acheive that degree of independence.
  • Code modules in a COM object can be plugged in to ASP or 100 other places.
    Code modules in C with appropriate PHP linkage are only for PHP, and are potentially more difficult to write.
  • ASP is almost always available on external web hosts, if they use Windows servers. Windows-based hosting tends to cost a bit more than Linux-based hosting, especially with SQL Server is provided.

Update (2007): PHP and ASP (now ASP.NET) have changed considerably since I wrote this; I suggest looking around for a more current comparison if you need to select between them now.

Improving Delphi Object Pascal

In a conversation between me and others in a newsgroup thread a while
back, I made some comment about not caring for the Object Pascal syntax
in some way. Someone asked:

> If you dislike Pascal so much, please explain what you like and
why.

This is a slightly more detailed answer to the question than I presented
at the time:

I actually like Delphi / OP, just not as much as I could. In case
you are interested, here are some things I wish were different:

  • I find the begin and end keywords to be needlessly verbose.
  • Control structures could have matching, non-optional blocks… like
    Modula-2 or (!) VB. if .. then .. endif would be more concise than "if
    .. then begin .. end", and make it easier to read code and prevent
    bugs. The whole begin/end thing really belies Pascal’s origin as a teaching
    language. When you write 2-page programs, it doesn’t matter if begin/end
    is verbose.
  • Case insensitivity permits sloppy coding.
  • Now that I’ve used Java quite extensively, I am really sold on garbage
    collection as a Very Good Thing for large-scale projects.
  • I wish there was a more effective structure for handling large amounts
    of code, other than the flat module structure. Java packages are nice.
  • I wish the RTTI covered everything about the class, not just published
    properties.
  • Why do we have to do:
  •   try
        try
          // yada
        except
          // yada
        end;
      finally
        // yada
      end;
    

    rather than

      try
        // yada
      except
        // yada
      finally
        // yada
      end;
    

    Borland could easily allow the latter, short and clear syntax.

The underlying point to all of this is that Object Pascal is Borland’s language;
they can do anything they want with it. The things above are within their
power to change; it’s not like that are complying with a standard.

But do I really want them to change all this? Probably not. Would I choose
OP for my code if it weren’t for the great stuff around it (the IDE, VCL,
weatlh of third party components, etc.)? Definately not.

In my opinion, the core strength of Delphi is not the language. It’s the IDE, VCL,
lightning-fast compiler, linker, and overall environment which have made it possible for Delphi to have
a vast array of available plugin components. Delphi has attracted a remarkable
number of vendors of high quality components. Using those components as well
as Delphi’s (object-oriented) core features, it is often possible to build a working solution in Delphi
much sooner than would be possible with another tool… and that is what I
like most about Delphi.

Web Services

There has been a lot of buzz recently about "Web Services". A short examination shows that essentially a web services is an RPC (remote procedure call), generally across the internet, using SOAP/XML over HTTP.

RPCs are nothing new – so why all the excitement? Here are some reasons:

  • Web services work over the internet, through firewalls. Getting other RPC technologied to do this can be challenging.
  • Web services carry "WSDL" service descriptions, which will make it possible for software development tools to greatly automate the process of using them.
  • Web services are truly language-neutral; many other technologies carry baggage that belies their origin in one primary language.
  • Web services are text-based; the protocol is human readable and hence much more debuggable than (for example) IIOP, DCOM, RMI, etc.

Borland has made it near-trivial to expose functionality as a web service, or call web service functionity in Delphi 6. With just a few clicks the needed client or server side "stub" code is automatically generated, allowing you to use a web services as easily as any local function/procedure.

Many publicly accessible web services are listed at http://www.xmethods.net/

Windows Clients, Java Servers

Problem / Scenario:

You have server code in Java implementing business logic, or you want to have such code. Java is your strategic choice.

But… you have a need for a client application that will be a native Windows application, for whatever reason. Sample reasons: (1) they need to run quickly and smoothly on a factory floor full of Pentium 150 or slower machines with limited RAM. (2) they need to work in disconnected mode, or talk to local hardware, so a web application won’t work.

How do you write server code in Java (in EJBs, for example) but access it easily from a native Windows clients, for example a Delphi application?

Possible Solutions:

Solution #1: Talk JRMP from Delphi

Implement the Java RMI JRMP protocol in Delphi. This will be nearly impossible, since it is built on Java object serialization. So there are various approaches you could take.

Solution #2: Java on the Client, use JNI

Run Java on the client as well, and use JNI to communicate between Delphi and Java, then Java to do the client side RMI. This defeated the goal of keeping the client lean, though… a Delphi thin client can run well on an old, slow machine with 32 meg of RAM, Java can’t.

Solution #3: RMI-IIOP / CORBA

Some Java application servers can seamlessly (?) expose Java services (like EJBs) as CORBA objects. Borland has CORBA support available for Delphi. This will avoid the overhead of Java on the client, but is too vendor-specific for my tastes.

Solution #4: Your own Proxy on the server

Use a non-RMI way to communicate between the Delphi client and an extra “tier” at the server; this piece of middleware would communicate with Delphi using any of a number of methods, including DCOM. Then use JNI or other means to access the Java services on the same (server) machine.

Solution #5: ASTA-Java

ASTA has a product (though I don’t know if it’s in development, or ready to go) that provide an generic mechanism for invoking EJB operations, from a Delphi client. The challenge here is how to send and receive complex types, which are defined by Java classes.

Solution #6: Web Services with SOAP

Expose the server-side services as web services via SOAP. Choose an application server which will automatically expose your EJBs this way, if possible. Then use any available way to make a Delphi client talk SOAP. PureSOAP and Microsoft’s SOAP support are two possible ways. (This is really the most appealing choice to me, as of 2001.)

Solution #7: Homegrown web services

It’s really not all that hard to write wrapper code that exposes your server services via HTTP requests with parameters, via XML strings, etc. Such a thing would not be language specific, so the server could be on one language, the client in another. This solution has some appeal in cases where you want the pieces to be tightly “wrapped up” and not exposes in anything as standard as SOAP for some reason.

 

There many, many paths to use to get from point A to point B… if you have a different scenariou in mind, tell me about it and I will try to expand this page to cover it.

Need to do this for your own project? Consulting services are available.