The following rant has been brought to you after I, again, was not able to adapt an existing component, but had to resort to copy/paste reuse.
THIS IS A WORK IN PROGRESS...
Delphi is a very complex language. What started in Turbo Pascal 1.0 as a relatively simple language, has become an hideous Swiss army knife of ill-considered extensions and obsolete constructs.
Eiffel is a very simple, very clean language. It is easy to read, even for novices, and easy to learn.
Eiffel is built upon the open/closed principle. This principle states that:
Modules should be both open and closed:
- A module is said to be open if it is still available for extension. For example, it should be possible to expand its set of operations or add fields to its data structures.
- A module is said to be closed if it is available for use by other modules. This assumes that the module has been given a well-defined, stable description (its interface in the sense of information hiding). At the implementation level, closure for a module also implies that you may compile it, perhaps store it in a library, and make it available for others (its clients) to use. In the case of a design or specification module, closing a module simply means having it approved by management, adding it to the project's official repository of accepted software items (often called the project baseline), and publishing its interface for the benefit of other module authors.
Delphi only knows the closed principle. Anyone who ever tried to change an existing component knows the frustration when he detects that most of the stuff he needs to access is in a private section or cannot be overriden.
There are many, many ways to hide things in Delphi. To bury them, so noone can ever touch them. You can mark a routine or a property as private of course. But you can also define types and routines in the body of a unit so they're not accessible either.
In Delphi, realistically speaking, there is only one way of reuse, and that is the Copy/Paste principle. Except if the class you want to change is written by the all-knowing all-foreseeing designer. He will have made all the routines you ever want to access either accessible or virtual. The same for properties. Give him a thumb-ups from me when you meet him. If he exists, because I never had the privilege to meet him, nor see any of his code.
Here's the list of how you can cast your Delphi code into concrete:
On the importance of resuse, see also Daniel Moissett's comments.
Eiffel has garbage collection. No more memory leaks. In Eiffel you typically do not concern yourself with memory management. You might be concerned by releasing resources as soon as possible such as closing a file instead of postponing the close until the object becomes garbage collected, but that's all. There are some settings of the garbage collector you sometimes want to set, but these occassions are rare.
In Delphi you're in control. And don't make a mistake, else your application will leak memory. So your typical code is sprinkled with try...finally handlers.
And sometimes you don't have to release the memory, but it all depends. Take for example strings. Strings are garbage collected in Delphi. Except if they are PChars.
And you don't have to free an object if it inherits from IUknown. But woe, if it inherits from IUnknown and you still free it.
Perhaps some of this needs to be moved to a different page like Eiffel for Delphi programmers?
The simple answer is: because it is missing Design-by-Contract. Many programming languages share many of Delphi's shortcomings because of this. In order to control what a client may do with an object, programmers feel they have no other option than to hide their code.
The other reason is that the compiler writers felt they had to leave the hard stuff to programmers. Whole system analysis is extremely beneficial, but hard on the compiler writer.
NOTE: This HTML page requires a browser that supports XHMTL and Cascading Style Sheets 2. |