Why You Should be Using Interfaces and not Direct References

I’ve been going on and on about how you should be coding against abstractions and not implementations.  From there, it’s not a big leap to realize that you should be using interfaces as the main means to create those abstractions.  Some of you have been asking me about why I think this, so I thought I’d write a post about why I say it.  So, here it is.

First, though, I’ll talk a bit about interfaces, what they are, and how they work.  This will be far from exhaustive, but I’ll try to cover the bases, and direct you to better sources of information.

What are Interfaces?

So, the first question you might have is “What the heck is an interface anyway?”.  Well, that’s an interesting question.  The short, easy answer is that an interface is a declaration of functionality without an implementation of that functionality.  In Delphi, we can declare an interface like so:

type
  IGetHTML = interface
    ['{3C02359E-D6DA-40E0-A12E-30B239DA7D9F}']
    function GetHTML: string;
  end;

This is a very basic Delphi interface.  Interfaces consist of a name (in this case, IGetHTML) and a declaration of methods and properties.  An interface includes no “real” code or implementing functionality. It is purely a declaration of capability.  In this case, the interface says “Hey, when I am implemented, I’ll give you some HTML.”  The interface tells you what functionality is available.  It does not tell you how the functionality will be implemented.  In fact, the interface doesn’t care, and the user of the interface shouldn’t care either.  The implementation of the interface might do any number of things to get HTML – create it internally, grab it from a file, construct it based on the internal state of some other object, or just plain return random HTML snippets. The interface itself doesn’t care.  All the interface knows is that it’s implementer will return a string, and that presumably that string will contain some HTML.

Note that the declaration of the interface as a GUID right after the initial declaration. This GUID is used by the compiler to identify uniquely this interface.  Strictly speaking, you can use an interface without the GUID, but you can’t get very far using them as much of the RTL and most frameworks that take advantage of interfaces will require that they have a GUID.

Of course, the purpose here is to create an implementing class that has some meaning when it goes into “Get me some HTML” mode.  For instance, you might have a series of visual components on form designer that represent a web page.  When it comes time to render the HTML for the page, you might iterate over all of them and call their GetHTML methods, regardless of what their type is.   The point is that it doesn’t matter what the implementing objects are or what they do – they just produce HTML.

Implementing an Interface

But of course, as you’ve guessed,  an interface can’t do anything without an implementing class.  Delphi makes it really easy to implement interfaces.  To do so, you need to declare a class as implementing an interface, and then make sure that class implements all the methods in the interface. 

In order to implement IGetHTML, you might declare a class as follows:

type
  THTMLGetter = class(TInterfacedObject, IGetHTML)
    function GetHTML: string;
  end;

  function THTMLGetter.GetHTML: string;
  begin
    Result := '<html><body><p>You want some HTML?  I got your HTML right here!</p></body></html>';
  end;

Note that the the class declares IGetHTML after the base class.  (The base class is TInterfacedObject – we’ll get to that in a minute.) It declares and implements the GetHTML function required by the interface

Some things to note:

  • The class can have any number of other fields and methods that it needs or requires, as long as it has the methods defined by the interface. If you fail to provide all the necessary methods, the compiler will give you an error until you do.  The class above is a really simple example, but the implementing class can be as simple or complicated as necessary – just as long as it has a GetHTML method.
  • The base class can be any base class as long as it implements the necessary methods for Delphi’s interface reference counting.    (TInterfacedObject does this — again, more on that in a minute…) But I want to stress again – the base class can be anything.  It could be a class you created.  It could be a VCL class.  It could be TButton or TClientDataset or anything.  It doesn’t matter, and the interface doesn’t care, as long as you provide implementations for all the necessary methods.
  • A class can implement any number of interfaces, so you can have a class declaration like

    TMultipleInterfaces = class(TInterfacedObject, IThisInterface, IThatInterface, IAnotherInterface);

    wherein the TMultipleInterface class providesan implementation

  • Interfaces can inherit from other interfaces, so you can declare an interface like so:

    TChildInterface = interface(TParentInterface);
     

    In this way, the child interface will require an implementation for all its declared methods as well as those of its parent.

Some Suggestions for Using Interfaces

Here are a few things to think about when creating and dealing with interfaces:

  • Declare interfaces in their own unit, preferably one interface per unit.  This makes for small units, but interfaces should be defined separately from any implementation.  It’s very tempting to declare an interface and a class that implements it in the same unit, but you should resist this temptation.  Keep interfaces separate and completely decoupled from any particular implementation.
  • Generally speaking, it’s a good idea to have interfaces be specific and to the point.  If you have a large interface – one with many methods, you might consider breaking it down.  There are times when it’s okay, but don’t be afraid to have interfaces with just a handful of – or even one – methods.
  • Interfaces can be used as abstractions for your code, but not all interfaces are abstractions necessarily.  If you have a “leaky” abstraction, then your interface isn’t truly an abstraction.  A leaky abstraction is one which allows implementation details to sneak through.  Say you had an interface called IDataSource and that interface had a method called GetConnectionString.  Having that method appears to strongly imply the notion of a relational database, perhaps even a specific one like MS SQL Server.  An implementation of IDataSource might use a collection or a list, and so the notion of a connection string shouldn’t be part of the implementation.  In this case, the implementation detail of having a connection string has “leaked through” your attempt at abstracting the notion of  a data source.
  • Along those lines, if your interfaces are merely a reproduction of the public class you use to implement it, then it is very likely that you have a leaky abstraction.

What’s this TInterfacedObject All About?

Much of the coolness and power of Delphi’s interfaces comes from the fact that they are reference counted.  That is, the use of the interface is tracked by the compiler and the implementing instance, once created, is automatically freed when the compiler realizes that the number of references to a given interface variable is zero.  In this way, a Delphi developer can use interfaces without ever having to worry about the memory that they allocate because the compiler tracks all the uses and destroys the class instance for you when the interface is no longer reachable.  That is pretty slick, and I’ll talk a bit more about that below. 

So, given that, the compiler needs a way to do all that tracking.  It also needs a way to figure out which interface is what (remember the GUID from above?).  So, in order to do that, all classes that implement an interface need to declare and implement three methods:

function _AddRef: Integer; stdcall;
function _Release: Integer; stdcall;
function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;

The first two are called automatically by the compiler each time it sees that a reference is used (_AddRef) and goes out of scope (_Release).  The QueryInterface method is used to determine if the class implements a given interface.  I’m not going to go into much depth here, but you can at least understand now the declaration (and implementation) of TInterfacedObject:

TInterfacedObject = class(TObject, IInterface)
  protected
    FRefCount: Integer;
    function QueryInterface(const IID: TGUID; out Obj): HResult; stdcall;
    function _AddRef: Integer; stdcall;
    function _Release: Integer; stdcall;
  public
    procedure AfterConstruction; override;
    procedure BeforeDestruction; override;
    class function NewInstance: TObject; override;
    property RefCount: Integer read FRefCount;
  end;

...

function TInterfacedObject._AddRef: Integer;
begin
  Result := InterlockedIncrement(FRefCount);
end;

function TInterfacedObject._Release: Integer;
begin
  Result := InterlockedDecrement(FRefCount);
  if Result = 0 then
    Destroy;
end;

You can see the entire declaration of TInterfacedObject in the System.pas unit.  It basically does all the housekeeping of managing the reference count of the implementing object, and destroying it when the count gets to zero.

Some further things to note:

  • If you want reference counting for your interfaces, you need to either descend your implementing classes from TInterfacedObject, or declare similar functionality in your class.
  • You should never really ever have a need to call the three “magic” methods of TInterfacedObject.  If you feel the need to, you almost certainly are doing something you shouldn’t be.  Pay no attention to what the IDE’s code completion tells you, don’t call them or mess with them in any way. 
  • With regard to the previous note, it is interesting that you can call the methods on TInterfacedObject in your code despite them being protected.  Remember, they are part of the interface, and the interface doesn’t have the notion of private, protected, or public. 

How Do You Actually Use an Interface?

Okay, so how do you actually use one of these things?  Here’s a simple example of our simple interface as implemented by our simple object:

procedure GetMeSomeHTMLPlease;
var
  HTMLGetter: IGetHTML;
begin
  HTMLGetter := THTMLGetter.Create;
  ShowMessage(HTMLGetter.GetHTML);
end;

The first thing you probably notice is that the line of code creating THTMLGetter looks pretty “normal”.  But of course, the big difference is that HTMLGetter is declared as IGetHTML – an interface type, and not an object reference type.   The next thing you probably see is that once the interface is created and used that…… well, nothing happens.  There’s no try…finally block and thus no call to Free that you would normally see if HTMLGetter were declared as THTMLGetter and not an interface.  This is, of course, because the interface is reference counted, and the THTMLGetter instance will be destroyed automatically by the compiler at the end of the procedure. 

Okay, that’s a very cursory and very quick look at interfaces in Delphi.  A ton of better and more in depth information on how Delphi interfaces out there is only a Google search away.

Why Do You Want To Use Interfaces?

The what and the how are the easy part.  It’s not tough to figure out how this all works.  It’s the why that seems to be the sticking point for many – I know it was for me for a long time.  So here’s the real meat of the article – Why in the heck would you want to use these crazy things?

Well here’s why.

Ultimately, there is one bottom line reason why you should use interfaces in Delphi:  They provide a very thin – but very powerful — abstraction to your code.  That’s why.  Everything below is really an expansion on that one idea.

 

As I’ve said before, and I’ll say again:  A good developer codes against abstractions, and not implementations.  Interfaces are a great way to create abstractions.  If you want a thorough discussion on why this is a good idea, I suggest reading Erich Gamma on the topic – but I’ll talk a bit about it here.

If you program against abstractions, you can’t couple yourself to a specific implementation.  Interfaces allow you to make the coupling between your classes very loose.  Classes should be developed and tested in isolation with few or no external dependencies.  But they almost certainly have to depend on something.  And certainly once you have a well-designed class library created, you need to piece it together to create the system you need to build.  In the end, an interface is the lightest and thinnest thing that a class can depend on.  So, if you program primarily with interfaces, you can’t help but create very loosely coupled code.  And we all know that loosely coupled code is good.  So interfaces help produce good code.

But there’s more – interfaces also let you alter implementations, even at runtime.  Because you are dealing with an interface, and not an implementation, you can pick and choose what implementation you want when you want.  For instance, you can write code like this:

procedure EncryptSomething(aSuperSecretStuff);TBuffer; const aIWantToBeSafe: Boolean);
var
  Encryptor: IEncrypt;
begin
  if aIWantToBeSafe then
  begin
    Encryptor := TSuperDuperPowerfulEncryption.Create;
  end else
  begin
    Encryptor := TWhoCaresHowSafe.Create;
  end;
  Encryptor.Encrypt(aSuperSecretStuff);
end;

This is a silly example, but you can see how this can be very powerful – you can have a single interface and select the proper implementation as needed.  An example might be an ICreditCard interface where you instantiate different credit card implementations based on the choice made by your customer.  Because you aren’t tied to a specific implementation, you can use a single ICreditCard interface while making it easy to alter which implementation gets used.  That’s powerful.

And of course, you might think that your implementation of your interface is great, but it’s entirely possible that a better one comes along, and you want to be able to easily plug that new implementation in without having to radically change your code.  Interfaces make that quite possible.  A good rule of thumb is to “Always develop against interfaces and code as if a radically better implementation is just around the corner.” (That sounds too good to be my quote – sorry if I stole that from you. Winking smile )

But wait, there is more!  Interfaces are good for inter-module communications.  Say you have a large system with different teams working on different major modules.  Those teams are responsible for providing functionality in their own modules, and thus they are responsible for the integrity and quality of the code in their modules.  Let’s say you are on the Widget team, and you need the Sprocket team to do something for you.  You go to the Sprocket guys and say “Hey, I need to add a few things in the Sprocket code so that we can do some Sprocket-type stuff in our Widget.”  The Sprocket guys are going to laugh at you – like they are going to let you poke around in their carefully crafted system!  No, instead, they will likely ask you want you need, build the functionality, and hand you some code with an interface and a factory for creating an implementation of that interface.  They aren’t going to let you anywhere near their code – but they are happy to let you have an interface into that code.  You get what you want – some Sprocket functionality – and they don’t have to expose anything more than an interface to you.  And later, if they completely re-architect their code, what do you care?  Your interface still works, even if they completely change the internal implementation.  That’s a sound way to develop, all made possible because of interfaces.

And it doesn’t end there – interfaces make your code testable.  As noted above, because you are using interfaces you can readily substitute any implementation you want.  What if you are testing and you don’t want to connect to the production database?  You can simply provide a mock implementation for your database connection interface – one that only pretends to be the database and that returns canned data – and now you can test your code in isolation without actually connecting to a database. 

And finally, interfaces make it easy to implement design patterns and do things like Dependency Injection.  Most of the new patterns and practices – including Dependency Injection frameworks – are enabled because of the power and flexibility of interfaces.  If you choose not to embrace interfaces, then you are locking yourself out of new and effective programming frameworks and techniques.  Or, put another way, all the cool kids are doing interfaces, and you want to be part of the cool kid group, right?

Conclusion

Okay, so if you aren’t convinced by now, I don’t know what to say.  Interfaces are flexible and powerful and let you ensure that your code is decoupled, easy to update, testable, and protected. They enable you to write clean, powerful, easy to maintain code.  They enable the use of new, powerful frameworks and development techniques. 

What more could you want?

Delphi Pretty Good Practices #5 – Don’t Use Literals

If there is a bedrock, bottom line, everyone-should-follow-it-all-the-time rule in programming it is “The DRY Principle” – Don’t Repeat Yourself.  This simple rule states that you should write code once and only once, and that you shouldn’t allow the same code to be used all over the place.  Or, as the Wikipedia article deftly states: “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.”  Put more simply, it means that you shouldn’t have the same thing repeated all over your code, but that you should create a single identifier and use that in the many places where it might be needed.

As a practical matter, the DRY principle in its most basic form tells us that we should, as a matter of course, not use literals in our code, but instead should declare constants (or resourcestring types as we’ll discuss in a minute) and use those instead. That way, if you need to change the value for something, you can do it in a single place instead of having to make multiple, error-prone changes throughout your existing code.

For example:  Say you have a system that has an arbitrary number of required repetitions, say 17.  You might end up writing a whole bunch of code like this:

for i := 1 to 17 do 
begin 
  ProcessStuff; 
  DoSomeMoreStuff; 
end;

 

Now imagine that you have that kind of code all over the place, and then your boss comes around and says “Hey, we need to repeat all that stuff 18 times now, not just seventeen.” Well, if you haven’t followed the DRY Principle, you could very well end up with a lot of code to change.  And don’t use search and replace, because what if you change the 17 that is part of a variable name or something?  Things could get ugly fast.

Of course, the thing to do is to declare a constant:

const NumberOfRepetitions = 17;

and declare your loops as

for i := 1 to NumberOfRepetitions do

begin

  ProcessStuff;

  DoSomeMoreStuff;

end;

 

and now when your boss switches things up, you have but one simple change to make, and all is well.

 

Now this is a pretty simple, basic thing to do, but I’m constantly surprised at how often I find myself forgetting to do it.  (For instance, if you look through the code for TextScrubber, you’ll probably notice that I need to apply the DRY Principle to the TVersionInfo constructor in uTextScrubberTypes.pas.) You might be surprised how many literals you use in your code. I often take advantage of the syntax highlighting feature to scan code for specific colors for strings and numbers and replace them with constant values as much as possible. For instance, some code from TextScrubber used to look like this:

 

procedure TStraightTextMainForm.InitializeMainFormInformation; var IniFile: TIniFile; begin IniFile := TIniFile.Create(IniFileName); try TextScrubberOptions.ClickChoice := TClickChoice( IniFile.ReadInteger(‘Options’, cClickChoice, 0)); TextScrubberOptions.ShouldTrim := IniFile.ReadBool(cOptions, ‘ShouldTrimText’, False); finally IniFile.Free; end; end;

 

with a bunch of string literals.  Instead, now, I’ve declared two constants in the uTextScrubberConsts.pas unit

const

  cOptions = 'Options';

  cClickChoice = 'ClickChoice';

  cShouldTrimText = 'ShouldTrimText';

  cVersionLangCodePage = '040904E4';

and the new code looks like this:

 

procedure TStraightTextMainForm.InitializeMainFormInformation; 
var 
  IniFile: TIniFile; 
begin 
  IniFile := TIniFile.Create(IniFileName); 
  try 
    TextScrubberOptions.ClickChoice := TClickChoice( IniFile.ReadInteger(cOptions, cClickChoice, 0)); 
    TextScrubberOptions.ShouldTrim := IniFile.ReadBool(cOptions, cShouldTrimText, False); 
  finally 
    IniFile.Free; 
  end; 
end;

Those constants are also used when I write out information to the INI file, so that I can change the value in one place if I need to, and so that I can know that there won’t be any typographical errors in my strings that will cause a bug.  The same string value is always going to be used for the INI file entry.

Now let’s take a look specifically at strings.  Strings are a bit special because they are very often used to communicate information, and as such, they frequently need to be translated into other languages through the process of “localization”.  Windows provides an easy way to do this via string resources, and Delphi provides an easy way to create string resources via the resourcestring identifier.  These strings are then created as resources, making them easy to translate.  And “easy to translate” can often be, well, translated into “cheaper to translate” and that is a good thing.

Practically speaking, I apply this principle by placing as many const and resourcestring declarations as I can in a single file, thus centrally locating them for easy management and translation.  In our case with the TextScrubber project, I’ve created a file called uTextScrubberConsts.pas and put constants and resource string values into it.  If you look through the project code, you’ll probably notice that I need to apply the DRY Principle to the TVersionInfo constructor in uTextScrubberTypes.pas, even if it is keeping those constants within the unit.

One question that might get asked is “How do you choose what to make a const and what to make a resourcestring?”  My answer is that as a general rule, any string that could change without changing the UI or the functionality of the code, make a const.  Any string that, if changed, will trigger a change in UI or translation should be made a resourcestring.  There are exceptions to that, of course. More simply, a rule to use that anything that might get translated should be a resourcestring.

Now, this is a pretty simple “pretty good practice” to follow, but for you folks who have not been following this principle,  simply doing so can make your code more readable and maintainable.

Delphi Pretty Good Practices #5 – Don’t Use Literals

If there is a bedrock, bottom line, everyone-should-follow-it-all-the-time rule in programming it is “The DRY Principle” – Don’t Repeat Yourself. This simple rule states that you should write code once and only once, and that you shouldn’t allow the same code to be used all over the place. Or, as the Wikipedia article deftly states: “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.” Put more simply, it means that you shouldn’t have the same thing repeated all over your code, but that you should create a single identifier and use that in the many places where it might be needed.

As a practical matter, the DRY principle in its most basic form tells us that we should, as a matter of course, not use literals in our code, but instead should declare constants (or resourcestring types as we’ll discuss in a minute) and use those instead. That way, if you need to change the value for something, you can do it in a single place instead of having to make multiple, error-prone changes throughout your existing code.

For example: Say you have a system that has an arbitrary number of required repetitions, say 17. You might end up writing a whole bunch of code like this:

for i := 1 to 17 do 
begin 
  ProcessStuff; 
  DoSomeMoreStuff; 
end;

Now imagine that you have that kind of code all over the place, and then your boss comes around and says “Hey, we need to repeat all that stuff 18 times now, not just seventeen.” Well, if you haven’t followed the DRY Principle, you could very well end up with a lot of code to change. And don’t use search and replace, because what if you change the 17 that is part of a variable name or something? Things could get ugly fast.

Of course, the thing to do is to declare a constant:

const 
  NumberOfRepetitions = 17;

and declare your loops as

for i := 1 to NumberOfRepetitions do 
begin
  ProcessStuff;   
  DoSomeMoreStuff;
end;

and now when your boss switches things up, you have but one simple change to make, and all is well.

Now this is a pretty simple, basic thing to do, but I’m constantly surprised at how often I find myself forgetting to do it. (For instance, if you look through the code for TextScrubber, you’ll probably notice that I need to apply the DRY Principle to the TVersionInfo constructor in uTextScrubberTypes.pas.) You might be surprised how many literals you use in your code. I often take advantage of the syntax highlighting feature to scan code for specific colors for strings and numbers and replace them with constant values as much as possible. For instance, some code from TextScrubber used to look like this:

procedure TStraightTextMainForm.InitializeMainFormInformation;
var 
  IniFile: TIniFile; 
begin 
  IniFile := TIniFile.Create(IniFileName); 
  try 
    TextScrubberOptions.ClickChoice := TClickChoice( IniFile.ReadInteger('Options', cClickChoice, 0));
    TextScrubberOptions.ShouldTrim := IniFile.ReadBool(cOptions, 'ShouldTrimText', False); 
  finally 
    IniFile.Free; 
  end; 
end;

with a bunch of string literals. Instead, now, I’ve declared two constants in the uTextScrubberConsts.pas unit

const 
  cOptions = 'Options';   
  cClickChoice = 'ClickChoice'; 
  cShouldTrimText = 'ShouldTrimText'; 
  cVersionLangCodePage = '040904E4';

and the new code looks like this:

procedure TStraightTextMainForm.InitializeMainFormInformation; 
var 
  IniFile: TIniFile; 
begin 
  IniFile := TIniFile.Create(IniFileName); 
  try 
    TextScrubberOptions.ClickChoice := TClickChoice( IniFile.ReadInteger(cOptions, cClickChoice, 0)); 
    TextScrubberOptions.ShouldTrim := IniFile.ReadBool(cOptions, cShouldTrimText, False); 
  finally 
    IniFile.Free; 
  end; 
end;

Those constants are also used when I write out information to the INI file, so that I can change the value in one place if I need to, and so that I can know that there won’t be any typographical errors in my strings that will cause a bug. The same string value is always going to be used for the INI file entry.

Now let’s take a look specifically at strings. Strings are a bit special because they are very often used to communicate information, and as such, they frequently need to be translated into other languages through the process of “localization”. Windows provides an easy way to do this via string resources, and Delphi provides an easy way to create string resources via the resourcestring identifier. These strings are then created as resources, making them easy to translate. And “easy to translate” can often be, well, translated into “cheaper to translate” and that is a good thing.

Practically speaking, I apply this principle by placing as many const and resourcestring declarations as I can in a single file, thus centrally locating them for easy management and translation. In our case with the TextScrubber project, I’ve created a file called uTextScrubberConsts.pas and put constants and resource string values into it. If you look through the project code, you’ll probably notice that I need to apply the DRY Principle to the TVersionInfo constructor in uTextScrubberTypes.pas, even if it is keeping those constants within the unit.

One question that might get asked is “How do you choose what to make a const and what to make a resourcestring?” My answer is that as a general rule, any string that could change without changing the UI or the functionality of the code, make a const. Any string that, if changed, will trigger a change in UI or translation should be made a resourcestring. There are exceptions to that, of course. More simply, a rule to use that anything that might get translated should be a resourcestring.

Now, this is a pretty simple “pretty good practice” to follow, but for you folks who have not been following this principle, simply doing so can make your code more readable and maintainable.

Delphi Pretty Good Practices #4 – Do Work in Classes

This page was orginally published on Wed, 05/05/2010 – 10:29 on my Embarcadero blog.

The next principle for the “Pretty Good Practices” we’ll discuss is this notion:  Whenever possible and as much as possible, put functionality in a class –  preferably a class that can be easily unit tested, reused, and separated from any user interface.

TextScrubber demonstrates this via the use of the TTextScrubber class in the uTextScrubber.pas unit.  TTextScrubber is a simple TObject descendant that does all the work for the whole application, really.  It is a standalone class – you could take the uTextScrubber.pas unit and use it in most any project you cared to.  Because of this, it is also very easy to write unit tests for this class.  (We covered unit testing in my previous series “Fun with Testing DateUtils.pas”, but I’ll discuss Unit Testing in a later post in this series as well.)  The class attempts to follow the “Law of Demeter”, which says that classes should know as little as possible about outside entities.  The three principles of the Law of Demeter are as follows:

  • Each class should have only limited or hopefully no knowledge of other classes.
  • If a class must have knowledge of other classes, it should only have connections to classes that know about it as well.
  • Classes should never “reach through” one class to talk to a third class

In the case of TTextScrubber, it only knows about and utilizes the TClipboard class and nothing else.  It doesn’t try to grab things out of TClipboard or attach to or require any other class.  It pretty much minds its own business, utilizes the services of the clipboard, and provide an easy way to get at its functionality.  It endeavors to do one thing:  scrub text, by both straightening and “un-formatting” it.  It has short, sweet method bodies, and ensures that it doesn’t try to do too much beyond exactly what it is supposed to do.  Following the Law of Demeter tends to make your code more maintainable and reusable. By reducing dependencies, you ensure that a class is as flexible as possible and that changes to it don’t tend to have far reaching consequences.

So, to as large a degree as possible, you should endeavor to put the functionality of your program into classes.  One way to tell you are not doing this is if you tend to do “OnClick” programming, or relying on event handlers to do the work of your application.  The Pretty Good Practices way of programming would dictate that your event handlers would contain code that merely instantiated and used other classes instead of having the actual code in them to do the work of your application.

So for instance, most of the work in TextScrubber gets done in an OnClick event of the TTrayIcon component.  That code looks like this:

procedure TStraightTextMainForm.MainTrayIconClick(Sender: TObject); 
begin 
  MainTrayIcon.Animate := True; 
  case TextScrubberOptions.ClickChoice of 
    ccStraightenText: begin
                               DoStraightenText; 
                             end; 
    ccScrubClipboard: begin 
                                DoPurifyText; 
                              end; 
  end; 
end;

 

class to do the work.  It’s not always entirely possible, but I try to make as many of  my event handlers and methods follow this pattern of merely utilizing the functionality of external classes.  Doing so enables a few things:

  • It means that functionality is much easier to unit test.  Isolated classes with specific functionality make unit testing really easy.
  • Functionality is easier to share and reuse.  An isolated, decoupled class can easily be moved to new applications as it has few or no dependencies.
  • Lean event handlers mean that your user interface isn’t tightly coupled to the work code.  This means that adjusting or altering your UI is easier to do, and adjusting and altering the work code doesn’t mean a change in the way the UI works.

So, to sum up – always try to build standalone classes to do the work or your application.

Delphi Pretty Good Practices #3 – File Setup

Okay, hopefully by now you’ve read the introduction of this series, and you’ve downloaded (or better yet, pulled from source control) the latest version of TextScrubber and given it a once over.  In this installment, I’m going to discuss the file structure of the project and why I did things the way I did.

First, an admin note:  I’ve made some small changes to the code for TextScrubber.  You can get these by going to the main directory for your code and typing svn up.  They aren’t any big deal – comments, some cleanup and organization, but it sure is easy to get the latest changes, isn’t it.

Taking a look at the file set that makes up the TextScrubber project, you see a number of different files, each with a particular purpose. I’ll describe each file in turn, telling what its purpose is and why it exists.  Future installements will go in depth a bit more.


 
FileName Discussion
frmAboutBox.pas Every Application should have an About Box.  The About Box should display the Application Icon, give Version information, copyright notices, and contain a short description of what the application is or does.
frmStraightText.pas This is the “main form” for the application, but since TextScrubber doesn’t have a main for, but it simply a container for some non-visual controls.
frmTextScrubberOptions.pas Every application should have a single dialog that allows the user to set all the configurable options and preferences for the application.
NixUtils.pas NixUtils.pas is a general purpose file of handy utilities and routines that I’ve built up over the years.  I use it in TextScrubber, so I’ve included it in the project.  Normally, I keep this file in a separate directory.
uTextScrubber.pas This is the “workhorse” unit that contains the class that does all the work of the application.
uTextScrubberConsts.pas This file has one and only one purpose:  To hold all the constants for the project. It will include all constant declarations, as well as the strings declared with resourcestring.
uTextScrubberTypes.pas This file contains all the types declarations for the project, including classes, enumerations, records, etc.
uTextScrubberUtils.pas This file contains those little, standalone, “helper” routines that you use to build the product.  Routings that go into this unit are often considered as candidates to end up in NixUtils.pas, but most often, they are very specific to a purpose of the project.

A Note About Naming Conventions

For this project, I’ve used a pretty simple naming convention. For filenames, I put ‘frm’ at the front of forms, ‘u’ at the beginning of standalone units. DataModules would get ‘dm’. Constants start with ‘c’, and resourcestrings start with ‘str’.  Parameters are prefixed with ‘a’, and all local variables (well, almost all) are prefaced with ‘Temp’.  Those latter two help keep things straight inside class methods.  I try to make my identifiers descriptive, and I never worry about their length.  A well named identifier makes code clearer, and Code Completion can do all the work if you are worried about typing.  (But in my view, you should never worry about typing if typing less means writing unclear code…..)

I use those as a general set of rules, but I’m not dogmatic about it.  I try to be consistent for my and your benefit.  The exact rules of naming aren’t nearly as important as having a naming convention.  My recommendation is to find a system that you like and stick with it.  Naming conventions are a great source of religious debates. I generally leave that to others, and simply recommend that you find something that works for you and stick with it. 

More Detail to Come

I’ll be talking a bit more specifically about each of the files in future installments.  This entry should just give you a brief rundown on the basics.

Delphi Pretty Good Practices #2 – Source Control

 

This post was originally made on Fri, 04/23/2010 – 14:35 on my Embarcadero blog.

Okay, so for this first installment, I’ll be illustrating one of my core principles for developing applications:  All my code of any importance at all goes under source control.  All of it.
I’m all by myself – why should I use source control?
We ask about source control use on the annual survey, and a surprisingly large percentage of you are not using source control at all.    That as a bit of a surprise.  If you are working on a team of any size, using source control is a no brainer.  But even if you are working alone, using source control is a really good idea.
Why, you might ask?  Well, there are a number of good reasons:
  1. It’s good to be in the habit.  Sure, you may be working alone.  But in the future you may not be.  Or your “weekend hobby project” might turn into a popular project with many developers.  If anything like that happens, being in the habit of using source code control will stand you in good stead.
  2. It protects your code.  Since your code is stored in on a server apart from your development machine, you have a backup. And then, you can even backup the code on the server.  Sure, you can zip it all up any time you want, but you don’t get all the other benefits I’m listing here.
  3. It can save your butt.  Sometimes, you might accidently delete something.  You might make mistakes and change code that you didn’t want changed.  You might start off on some crazy idea when you are feeling a bit saucy, and then regret it.  Source control can save you from all of these by making it a piece of cake to revert to any previous state.  It’s like a really powerful “undo” feature.
  4. It allows you to “turn back time”. Say you are a shareware author. You like to release updates and new versions.  And say you get a support request from a customer that has a bug while using a version that is two major releases old. Source control lets you easily recreate the code base for that exact release and debug the problem that the user is seeing.
  5. It makes you think about your process.  Even if you work alone, you should be deliberate and organized in how you write code. If you are in the habit of checking your code into a source control system, you’ll end up thinking more about what you are doing, how you are doing things, and you’ll end up being more organized and deliberate.
  6. It gives you the freedom to experiment.  Somewhat the mirror image of the previous reason, source control gives you the freedom to say “What the heck, I’ll try that wacky way of doing things!”  Since you know that you can always get back to a known good state, you can be free to experiment and try something that might otherwise hesitate to do. And that experiment might just prove to be a brilliant way to do it.
  7. It lets you backtrack.  Even when we work alone, we can’t remember every single thing we do and every single change we make.  And I bet at least once in your life you’ve looked at some code and said “Huh? When the heck did that happen?”  With a source control system, you can answer that question very easily.  You can track where a specific change came from and when it was made and maybe even the comment you made when you checked the change in.
  8. It lets you see what changed.  Sometimes, things start acting up. Maybe a section of your application that you haven’t used in a while is behaving differently than you expected.  Maybe it is totally broken and you have no idea why.  Source control can let you track the process and peer into the history of a specific chunk of code to see what changes were made and how those changes affected the project as a whole.
I’m sure you all can think of more reasons.  Bottom line is that if you aren’t using source control, then you should start, no matter what your development situation is.  ZIP files just aren’t going to cut it.  Seriously.

Okay, I’m convinced. What now?

I’m convinced that my points above are so compelling that you are in violent agreement with me, so I’m going to make you use the Subversion client to get the code for this series’ demo project, TextScrubber. TextScrubber is only available from SourceForge under Subversion.   If you don’t use Subversion for source control, you should at least have the command line client on your machine, because Subversion is everywhere, and you should at least know how to get code from code repositories that use it.  I know that there are other well known source control management systems out there.  Git and Mercurial are growing in popularity, but Subversion is probably the most widely used source control system out there.  We use Subversion internally here on the RAD Studio team.

Getting the Subversion Command Line Client

So the first thing you’ll need to do is to get the Subversion client.  (If you already have the client, you can skip this whole section) A whole lot of projects out there — whether on SourceForge orGoogleCode or CodePlex — use Subversion, so having the client is pretty useful.  It’s also small and easy to use, so here’s how you get it:
  1. I’d recommend getting the binary package from Collabnet:  In order to do that, you’ll have to get an account with them. You can sign up here:  http://www.open.collab.net/servlets/Join  If you don’t want to do that, you can get the binaries here as well:  http://subversion.tigris.org/servlets/ProjectDocumentList?folderID=91
  2. Go to:  http://www.collab.net/downloads/subversion/ and choose the second download entitled:  “CollabNet Subversion Command-Line Client v1.6.9 (for Windows)”
  3. There is a big orange button there that says “Download”.  Note again that this is the second button on that page as we are downloading the client only.
  4. Press the button and download the file.
  5. Execute the installer that you downloaded.
There, you just installed the Subversion client.  The path to the client should now be on your DOS PATH (if it isn’t, you can put it there) and you should be all ready to go on the command line.
Note: Subversion has only very recently been brought under the umbrella of the Apache Project. As such, it is licensed under the very friendly Apache License, Version 2.0.   It was originally founded by Collabnet, but moved over to be a part of the Apache set of tools just this past February.  It is open source, so if you are really hard core, you can download the source and compile it all yourself.  Me?   I’m not that hardcore. I use the convenient binaries provided by the good folks at Collabnet.

Grabbing the Code for TextScrubber

Once you have the command line Subversion client installed (it’s called svn.exe, by the way), you can easily download the code for TextScrubber.  Seriously, it’s like falling off a log.  Just do the following:
  1. Open a command window and go to the parent directory where you want the code to go.  For instance, if you want the code to go into c:\code\textscrubber, you want to start with your command prompt at c:\code
  2. Issue the following command:
svn co https://textscrubber.svn.sourceforge.net/svnroot/textscrubber/trunk textscrubber
‘co’ stands for ‘checkout’. The second parameter is the URL for the ‘tip’ of the Subversion repository. This command will pull from SourceForge the most recent version of the code into the \textscrubber\trunk directory. That last parameter there is the name of the subdirectory that will be created and filled with the code from SourceForge.
That’s it. You now have the most recent, up to date code for TextScrubber on your machine.  You are all ready to start straightening and unformatting text!

Using Subversion

In the future, if I make updates to the project, then all you need to do is to navigate to the \textscrubber\trunk directory and do a “7up” or “svn up” command, and it will get the latest and greatest code for you in a jiffy.  Can’t be much simpler than that. That’s the command you’ll end up using the most, probably.
Since it is so popular and commonly used, there is a lot of information about using Subversion out on the web.  I’ve found this tutorial to be very useful, as well as the book (written by the same guys that wrote the tutorial..): Version Control with Subversion

Another useful tool for using Subversion is TortoiseSVN.  TortoiseSVN is a Windows shell plug-in that provides all the functionality of the Subversion client in an easy to use GUI.  Below is a screen shot of the TortoiseSVN Log Window for the TSmiley project on SourceForge.

TortoiseSVN is also an open source project, so you can get it for free.  If TortoiseSVN proves to be valuable to you, I’d also encourage you make a generous donation to the project.  I did.

Getting and Setting Up the Subversion Server

If you make the wise and sagely decision to go ahead and use source control for all of your code, you can easily set up the Subversion server.  You can, of course, download the Collabnet binaries and install them, but if you want to go the pathetically easy route (which I recommend), you should download and install Visual SVN Server.  I’m not even going to go through the steps to installing the server, because they are not much more than download, run the install, and you are done.  That’s it.  It takes like two minutes.  Seriously. They even provide you with a nice Management Console application for administering the server, making that really easy as well.
(And while you are looking at VisualSVN Server, you can consider upgrading to their Enterprise edition.)

Now, I myself run the full server (Apache, etc. – the whole ball ‘o’ wax….) on my local machine and use it to manage my code.  This enables me to browse my code in a browser and do other things that are supported by a full blown server   But that might be a bit of overkill for some of you (I’m weird that way – I just want the “full” experience and like to be in learning mode…) and you might not want to do that.  Instead, you can simply create local repositories on your local disk.   The Subversion tutorial above can show you how to do that.

I have been using the server locally since I use a laptop exclusively and move it between work and home.  But I think I’ll set up the server on a machine at home and check in there. That way, my code will be stored on a separate machine.

More About Source Control

As you can probably tell, this post isn’t meant to be a primer on Subversion or source control in general.  The tutorial I listed above is a good place to learn about Subversion.  If you want to learn more about source control in general, I recommend reading Source Control HOWTO by Erik Sink.  Eric is a really interesting guy who has a great blog and also runs SourceGear, a commercial vendor of developer tools including Vault, a source control management tool that I recommend considering.  You might be interested to note that Vault is free for single users.
That’s it.
And so that is the first “Pretty Good Practice” for developing with Delphi: Manage your code with a source control system.

So, what do you think?  Are you ready to make the move to source control management?

 

Delphi Pretty Good Practices #1

This article was originally published on Mon, 04/19/2010 – 16:38 on my Embarcadero blog.

A while back someone (I can’t remember who, sadly, sorry to the person who made the suggestion…) suggested that someone do a series of articles about “the best practices on how to develop a Delphi application”.  That’s a good idea.  There are a lot of ways to do things, and clearly there are some good way and some bad ways, some okay ways and some really cool ways to develop with Delphi.
This series of articles will cover my personal ideas behind a good way to organize and build a Delphi application.  I’ll build a small application that does a few things.  I’ll organize the application in such a way that it illustrates some techniques that I believe are a good way to organize things.  I will explain my reasoning and in doing so I hope that you guys learn something.  This won’t be an exhaustive list or collection of ideas.

What I will not do is pretend that what I do and the way I do it is the only way to do things.  Heck, it may be that you end up thinking the way I do things is ridiculous.  I’ll let you all be the judge of that.   If you guys have different ideas, please feel free to express them.  If you like what you see, let me know.  I’ve been using Delphi for a long time, and so I think I’ve learned a thing or two along the way, but I’m not the world’s greatest Delphi developer and I certainly won’t claim to be the final arbiter of how things should be done.  I generally don’t like the term “Best Practices”, so I’ve titled this using “Pretty Good Practices”.

My goal here, really, is to be informative and stimulative and to evoke conversation and discussion.  I have developed a way of doing things over the years and I’ll be outlining them in this series of articles.  I don’t believe that this series will be all inclusive – that is, I won’t be covering every single aspect of every single development practice that I’ve ever thought of. Again, I hope merely to stimulate some discussion and do my humble part to  improve the way Delphi applications are developed.

The application I’ll use as an illustration is one that I use practically every day.  I call it “TextScrubber”, and it is a simple application that resides in the tray and let’s me “clean up text”, either by removing formatting, removing line breaks, or both.  I use it when I copy text from the web or from an MS Word document that contains formatting information that I in turn want to paste into another document when I don’t want the formatting to come along.  I copy the text, click on the icon in the tray, and the text is “scrubbed” and put back on the clipboard.  (It is basically a much simpler version of PureText – a product that I heartily recommend that you use if you want this kind of functionality.)  TextScrubber is actually a very simple application with not a lot of code, but I’ve laid it out in such a way that it illustrates many of the methods that I have developed over the years.  Thus, I hope it will suffice to illustrate the things I want to discuss.

To start, I’ll talk about a few general ideas that drive how I do things. These are the general ideas that drive what I do when I develop:
 
  • Any code of consequence at all should be managed under source control, even if I am the only one using and writing the code.  I use Subversion for this. I actually run the Subversion server on my local machine, but you don’t need to do that.  You can manage a Subversion repository merely as a set of local files, if you want.  But even if you develop all alone, I think using source control is a great idea.
  • I want everything I write to be easily expandable and scalable.  I try to organize and write code that can easily be extended and enhanced.  I try to write classes that have a sensible hierarchy and that can be easily inherited from.
  • I want my code to be testable.  I want to write it in such a way that it is conducive to writing unit tests.  I want it to be easy to isolate and easy to find problems if they crop up.
  • To as large a degree as possible, I separate the logic of an application from the user interface.  I don’t go full bore into an MVC application usually – that almost requires a special framework, but I do try very hard to separate out functionality into separate, testable classes.
  • I want my code to be well modularized.  That is, I want each class and each unit to have a single purpose, and be linked to other units and classes as loosely as possible.

What would you add to this list?  What are some of the general rules you try to follow when developing an application?

Dependency Injection Series

Update in July, 2012:  This series of articles was written using an early version of the framework.  Therefore, much of the code I posted might not compile or make sense.  But the lessons here are all still the same.

I have written a series of articles on Dependency Injection with the Delphi Spring Framework.  I’ve centralized them here:

Fun With Testing DateUtils.pas #8

Note: This is a “reprint” of content from my blog on Embarcadero.com when I was working there.  They’ve since shut down my blog and the content is gone.  I’m republishing it here.  See the main article for more information.

Okay, first up:  I’ve put the tests and updates for DateUtils.pas on CodeCentral. 

So far, I’ve been writing tests in a pretty organized way.  But I write each individual test, one at a time.  I often end up writing a lot of “piece-meal” tests by hand.  I end up with a lot of code that looks like this:

procedure TDateUtilsTests.Test_IncMinuteBeforeEpochAdding;
var
  TestDate, Expected, TestResult: TDateTime;
begin
  TestDate   := EncodeDateTime(945, 12, 7, 13, 34, 26, 765);

  TestResult := IncMinute(TestDate, 1);
  Expected   := EncodeDateTime(945, 12, 7, 13, 35, 26, 765);
  CheckTrue(SameDateTime(TestResult, Expected), Format('IncMinute couldn''t add
     a single minute to %s ', [DateTimeToStr(TestDate)]));

  TestResult := IncMinute(TestDate, 45);
  Expected   := EncodeDateTime(945, 12, 7, 14, 19, 26, 765);
  CheckTrue(SameDateTime(TestResult, Expected), Format('IncMinute couldn''t add
     45 minutes to %s ', [DateTimeToStr(TestDate)]));

  TestResult := IncMinute(TestDate, MinsPerDay);
  Expected   := EncodeDateTime(945, 12, 8, 13, 34, 26, 765);
  CheckTrue(SameDateTime(TestResult, Expected), Format('IncMinute couldn''t add
     a days worth of minutes to %s ', [DateTimeToStr(TestDate)]));
end;

Now those tests are fine, but they aren’t very easy to write. Adding another one either takes a lot of typing, or runs the risk of cut-n-paste errors that slow things down.  Wouldn’t it be cool if there were a more systematic way of running tests that made it easier to add a specific test?

Well, one of our R&D guys did that for the DateUtils.pas unit.  Denis Totoliciu works on the RTL as part of our Romanian team.   Now Denis is a pretty smart guy and a big proponent of test driven development.  He has been busy writing tests for DateUtils.pas as well, and he’s a lot more efficiency minded than I am.  As a result, he’s also a lot more productive and prolific. This is why I am the manager and he is the developer.   

If you look at the code for the unit tests, you can probably see where he has written tests and where I have (though I’ll be taking up Denis’s method for future tests).  He recognized that most tests for any given DateUtils.pas routine are all going to be pretty similar, so he created a system whereby you create a large array of data, and then iterate over that array and run the tests on the data in each element. This way, if you want to add tests, you can simply add an item to the data array with the input and expected output. 

For instance, when he first did this, I noticed that he didn’t always add data to test dates before the epoch.  Since I’ve learned the hard way that whenever you test a routine you should also test dates before the epoch as well as after, it was really easy for me to simply add the data to the array and expand the number of tests that were run. 

Here’s how this looks:

procedure TDateUtilsTests.Test_DayOfTheMonth;
const
  CMax = 16;

type

  TDateRec = record
    Year, Month, Day: Word;
    ExpectedDay: Word;
  end;
  TDates = array [1..CMax] of TDateRec;

const
  CDates: TDates = (
    (Year: 2004; Month: 01; Day: 01; ExpectedDay: 01),  // 1
    (Year: 2004; Month: 01; Day: 05; ExpectedDay: 05),
    (Year: 2004; Month: 01; Day: 08; ExpectedDay: 08),  // 3
    (Year: 2004; Month: 02; Day: 14; ExpectedDay: 14),
    (Year: 2004; Month: 02; Day: 29; ExpectedDay: 29),  // 5
    (Year: 2004; Month: 04; Day: 24; ExpectedDay: 24),
    (Year: 2004; Month: 07; Day: 27; ExpectedDay: 27),  // 7
    (Year: 2004; Month: 12; Day: 29; ExpectedDay: 29),
    (Year: 2005; Month: 01; Day: 01; ExpectedDay: 01),  // 9
    (Year: 2005; Month: 01; Day: 03; ExpectedDay: 03),
    (Year: 2005; Month: 05; Day: 05; ExpectedDay: 05),  // 11
    (Year: 2005; Month: 07; Day: 12; ExpectedDay: 12),
    (Year: 2005; Month: 09; Day: 11; ExpectedDay: 11),  // 13
    (Year: 2005; Month: 02; Day: 21; ExpectedDay: 21),
    (Year: 2005; Month: 02; Day: 25; ExpectedDay: 25),  // 15
    (Year: 2005; Month: 04; Day: 10; ExpectedDay: 10),
     );

var
  TestDate: TDateTime;
  Expected: Word;
  Result: Word;
  i: Integer;
begin
  for i := Low(CDates) to High(CDates) do
  begin
    TestDate := EncodeDate(CDates[i].Year, CDates[i].Month, CDates[i].Day);
    Expected := CDates[i].ExpectedDay;
    Result := DayOfTheMonth(TestDate);

    CheckTrue(SameDate(Expected, Result), Format('DayOfTheMonth failed
        for test %d.', [i]));
  end;
end;

Note that the first thing this code does is declare a really big array full of dates (all after the epoch, too). The array is of type TDates, which is simply an array of type TDateRec. All of these types are declared locally, so each routine can have it’s own separated data types. The array holds all the inputs as well as the expected result. Each element of the array is informally numbered, and when one fails, the number of the test is identified by the counter used in the for statement.

Now for me to add a bunch of tests that use data before the epoch is a piece of cake. I merely change the value for CMax and then make the array look like this:

const
  CDates: TDates = (
    (Year: 2004; Month: 01; Day: 01; ExpectedDay: 01),  // 1
    (Year: 2004; Month: 01; Day: 05; ExpectedDay: 05),
    (Year: 2004; Month: 01; Day: 08; ExpectedDay: 08),  // 3
    (Year: 2004; Month: 02; Day: 14; ExpectedDay: 14),
    (Year: 2004; Month: 02; Day: 29; ExpectedDay: 29),  // 5
    (Year: 2004; Month: 04; Day: 24; ExpectedDay: 24),
    (Year: 2004; Month: 07; Day: 27; ExpectedDay: 27),  // 7
    (Year: 2004; Month: 12; Day: 29; ExpectedDay: 29),

    (Year: 2005; Month: 01; Day: 01; ExpectedDay: 01),  // 9
    (Year: 2005; Month: 01; Day: 03; ExpectedDay: 03),
    (Year: 2005; Month: 05; Day: 05; ExpectedDay: 05),  // 11
    (Year: 2005; Month: 07; Day: 12; ExpectedDay: 12),
    (Year: 2005; Month: 09; Day: 11; ExpectedDay: 11),  // 13
    (Year: 2005; Month: 02; Day: 21; ExpectedDay: 21),
    (Year: 2005; Month: 02; Day: 25; ExpectedDay: 25),  // 15
    (Year: 2005; Month: 04; Day: 10; ExpectedDay: 10),
    // Before the Epoch
    (Year: 1004; Month: 01; Day: 01; ExpectedDay: 01),  // 17
    (Year: 1004; Month: 01; Day: 05; ExpectedDay: 05),
    (Year: 1004; Month: 01; Day: 08; ExpectedDay: 08),  // 19
    (Year: 1004; Month: 02; Day: 14; ExpectedDay: 14),
    (Year: 1004; Month: 02; Day: 29; ExpectedDay: 29),  // 21
    (Year: 1004; Month: 04; Day: 24; ExpectedDay: 24),
    (Year: 1004; Month: 07; Day: 27; ExpectedDay: 27),  // 23
    (Year: 1004; Month: 12; Day: 29; ExpectedDay: 29),

    (Year: 1005; Month: 01; Day: 01; ExpectedDay: 01),  // 25
    (Year: 1005; Month: 01; Day: 03; ExpectedDay: 03),
    (Year: 1005; Month: 05; Day: 05; ExpectedDay: 05),  // 27
    (Year: 1005; Month: 07; Day: 12; ExpectedDay: 12),
    (Year: 1005; Month: 09; Day: 11; ExpectedDay: 11),  // 29
    (Year: 1005; Month: 02; Day: 21; ExpectedDay: 21),
    (Year: 1005; Month: 02; Day: 25; ExpectedDay: 25),  // 31
    (Year: 1005; Month: 04; Day: 10; ExpectedDay: 10)
  );

And now I have a complete set of tests for dates before the epoch.  Piece of cake.  If I find specific dates that I want to test, then I can easily add those as well.  The actual code that runs the tests doesn’t care how many elements there are in the array; it will happily process all the data passed to it.  Now, you don’t get to write as many fun error messages as you do when you do it the more straightforward way, but that is a small price to pay for the efficiency gained.

And if a test fails, you are given the test number, and you can see the test data and expected result right away right in the code.

And here’s a further aside for those of you who don’t like me using random dates:  this test for EncodeDateDay and DecodeDateDay tests every single day in every single year.   

procedure TDateUtilsTests.Test_EncodeDateDay_DecodeDateDay;
var
  TempYear, MinYear, MaxYear: Word;
  RYear: Word;
  TestDate: TDateTime;
  RDayOfWeek: Word;
  TempDay: Integer;
  RDayOfYear: Word;
begin
  // Test every possible day for every possible year.
  MinYear := MinAllowableYear; // 1
  MaxYear := MaxAllowableYear; // 9999
  for TempYear := MinYear to MaxYear do
  begin
    for TempDay := 1 to DaysPerYear[IsLeapYear(TempYear)] do
    begin
      TestDate := EncodeDateDay(TempYear, TempDay);
      DecodeDateDay(TestDate, RYear, RDayOfYear);

      CheckEquals(TempYear, RYear,
        Format('EncodeDateDay() / DecodeDateDay() failed.
             TempYear = %d; RYear = %d', [TempYear, RYear]));
      CheckEquals(TempDay, RDayOfYear,
        Format('EncodeDateDay() / DecodeDateDay() failed.
             TempDay = %d; RDayOfYear = %d', [TempDay, RDayOfYear]));
    end;
  end;
end;

It takes a little longer to process, but it covers every single possible test case, I believe.

So that should cover it.  I think I’ll wrap the series up here.  I’m almost done writing tests for DateUtils.pas.  When I am done, I think I will move on to StrUtils.pas. 

Fun With Testing DateUtils.pas #7

Note: This is a “reprint” of content from my blog on Embarcadero.com when I was working there.  They’ve since shut down my blog and the content is gone.  I’m republishing it here.  See the main article for more information.

Okay, so after that last post, and after all the fixes that I did, things have settled down a little bit.  I thought I’d take advantage of this interlude to tell you some interesting things about TDateTime in Delphi, because along the way here, I have discovered a thing or two along that way that was surprising.

The first thing that you might be interested in is that the calendar used by the Delphi TDateTime has a specific name:  The Proleptic Gregorian Calendar.  Calendars, of course, have been notoriously inaccurate over the years, and even ours isn’t entirely accurate in that we have to have leap years every so often (and not as often as one might believe…). We even have these “leap seconds” every once and a while, though the notion of being able to measure things down that precisely is kind of weird.  Starting with the Romans – Julius Caesar, actually – the Western world used the Julian calendar.  And that worked pretty well, actually.  The Julian calendar worked pretty well – it has 365 days and a leap year every four years – but it wasn’t entirely accurate, and (as you can read in the Wikipedia entry) politics got involved, and the calendar got out of whack pretty easily and pretty often.

So anyway, as you may have noticed, some of the tests that I have written include some pretty big time increments – like 1000 years worth of seconds and things like that.  And I also wanted to makes sure that the incrementing routines worked across the epoch of December 30, 1899.  So I had to be able to do some pretty serious calculations.  I found a pretty good website to do those calculations called timeanddate.com.  This site has a bunch of calculators for measuring between dates and time and for calculating a date based on distance from another date.  So I used it to figure out what the date was if you decremented two hundred years worth of seconds (that’s 6,307,200,000   seconds for you math geeks….) from, say, Noon on June 30, 1945.  (It’s not exactly noon on  June 30, 1745 due to leap days.)  Well, I would calculate it, and then write the tests, but they would fail because my expected result was always eleven days different than the test result.  Eleven days – how weird, huh?

Well, here’s the deal.  Somewhere along the way, the really smart guys who figure out this kind of thing came up with a new calendar – the Gregorian calendar.  It’s different from the Julian calendar, and starting in the 16th century, the world gradually converted over to use the Gregorian Calendar instead of the Julian calendar (A good chunk of Europe started in 1582, and the last folks to make the switch were the Russians who didn’t change until 1918).  But to do that, you usually had to skip about 10 or 11 days.  Great Britain and all of its possessions (including the colonies that would become the United States) made the switch in 1752.  Therefore, in the English world, the day following September 2, 1752 was September 14, 1752.  There was no September 3 – 13, 1752.  Just didn’t exist.  Once I discovered that, it explained the missing eleven days.

But what does this mean for our trusty TDateTime?  For a minute there I was afraid that I was going to have to do all these special calculations to account for this unusual anomaly, but then I came to my senses and realized:  That can’t be right.  And I was right.  Instead, Delphi uses, as I mentioned above, the Proleptic Gregorian Calendar – that is, it assumes that the Gregorian calendar is in force all the way  back to January 1, 0001.  So for TDateTime, there is a September 4, 1752 (Noon on that day is the value: -53807.5) and every single date “like normal” all the way down to Year 1.  This makes sense, because trying to devise a calendaring system that keeps track of all the vagaries of the Julian calendar system would be basically impossible.  Instead, Delphi uses a system that “makes sense” for a computer.  A number of other languages and tools use the Proleptic Gregorian Calendar, including MySQL and PHP.

That was probably more than you wanted to know about TDateTime, but it’s all stuff that you have to know to write a complete test suite for DateUtils.pas. So far, that summarizes the issues that I’ve run across in testing the unit. I have a ways to go to have a complete test suite, but if I run across more issues, I’ll post on them.

The next post I do will be about a testing scheme that one of our developers, Alexander Ciobanu, devised to make writing tests for testing date functions a little easier.