Amazon.com Widgets Nick Hodges | A man's got to know his limitations

Flotsam and Jetsam #50

By Nick at November 23, 2011 12:32
Filed Under: Delphi, Flotsam and Jetsam, Software Development

Flotsam and Jetsam #49

By Nick at November 09, 2011 13:46
Filed Under: Software Development, Flotsam and Jetsam, Delphi
  • Hallvard Vassbotn has been sighted in the wild! Hallvard is an amazing developer and a great writer, and I’m delighted at the prospect of him starting to blog again, especially given his propensity to stretch Delphi language and RTL features to the limit.  Given all the new things that have happened in these areas since Hallvard’s last blog  post, one can only hope for really interesting stuff.
  • Fun to see people taking up the Dependency Inject mantle – here’s an article by Yanniel Alvarez Alfonso on a simple example of DI using DelphiDean Hill has a very good article about Software Flexibility that discusses how Dependency Injection can make your software more flexible and adaptable.   If my efforts have sparked an interest in Dependency Injection, I couldn’t be happier.  I’ll say it again:  If you aren’t using even the most basic form of Dependency Injection, then you are doing it wrong.
  • ninite.com is a really cool site that provides a valuable and helpful service.  It allows you to create a single install for a pretty broad and selectable collection of popular software.  This is particularly useful when setting up a new machine.  There’s always a million of these things that you want to install – Skype, Chrome, Firefox, your favorite IM client, media players, various utilities, etc. --  and Ninite.com allows you to select all of these and get a single installer for them all.  It does all the “smart” things that you want it to like get the 64-bit version if possible, ensures you have the latest versions -- and best of all -- it clicks all the “Next” buttons so you don’t have to.  Sweet.
  • I tweeted this notion this week -- “Crazy Idea of the Day: Every class that raises an exception unique to itself should have it's own exception type to raise. “ – and I thought that I’d expand a bit on it here.  One of my pet peeves is unclear error messages.  Somewhat of a corollary to that is the irritated feeling you get when an exception is raised, but you can’t tell right away where it came from. Thus was born the notion above – that if your class is raising an exception unique to itself (i.e., not something “normal” like EConvertError or EFileNotFoundException or something like that….) it should be raising an exception type defined specifically for the class itself.  This way, you can put a very descriptive error message in the exception, and the developer or user seeing the exception can know exactly where it came from. In addition, it allows anyone using  your class to easily trap exceptions specific to your classes.  I’ve been doing this for years, but have never seen anyone in the Delphi community really discuss it.
  • Every once and a while, I like to remind folks that they can go to the Delphi UserVoice page and vote for their favorite new features in Delphi.  This is totally unofficial, but it is interesting.  I’m still an admin there, so it’s always fun to mark items done as they get shipped. (I confess that it is also fun to close and/or reject requests that are……. not well thought out…?)  Currently, this item – “Better GUI separation and abstraction” -- is the top voted thing on the whole site, and I’m wondering if that really is indeed what the Delphi community wants the most.  In any event, you can certainly go there and vote and perhaps influence the future of the product. 

Getting Giddy with Dependency Injection and Delphi Spring #9 – One Interface, Many Implementations

By Nick at November 07, 2011 20:27
Filed Under: Delphi, Software Development

So far, we’ve been registering interfaces and implementations in a one-to-one relationship.  Each interface has one implementing class registered against it.  But what if you want to implement an interface many different ways, choosing which implementation to use depending on user input or other external factors?

As always, you can download the Delphi Spring Framework from GoogleCode.

Well, lucky for us, the Spring Container lets us do just that.  The Delphi Spring Framework container registration system allows you to specify a name for any giving implementation registration, thus distinguishing different registrations from on another, even if you register multiple implementers for the same interface. 

If you register multiple implementers for a given interface without specifying a name for each one, then the “last one in wins'”.

So, for instance, you might declare a simple credit card interface as follows:

type
  ICreditCard = interface
    ['{6490640C-0E2B-4F7D-908C-0E6A74DCC0A0}']
    function IsValid(aCreditCardNumber: string): boolean;
    function ChargeAmount(aCreditCardNumber: string; aAmount: Double): Boolean;
  end;

There are any number of credit cards that customers might want to use, so you’ll need to have credit card implementations for the various common vendors:

  GlobalContainer.RegisterType<TVisa>.Implements<ICreditCard>('VISA');
  GlobalContainer.RegisterType<TMasterCard>.Implements<ICreditCard>('MasterCard');
  GlobalContainer.RegisterType<TDiscover>.Implements<ICreditCard>('Discover');
  GlobalContainer.RegisterType<TAMEX>.Implements<ICreditCard>('AMEX');

This code registers four different classes (TVisa, TMasterCard, TDiscover, TAMEX) for the same interface (ICreditCard) via the string parameter on the GetService call.  Once these are registered, you can pick and choose whichever credit card processing class you want as the implementation of ICreditCard.  You can even change the selection at runtime based on, say, user input or different orders being processed, etc. 

For instance, if you have four radio buttons that allow the user to select one of four credit cards, you can do the following:

var
   CurrentCard: ICreditCard

...

procedure TMultipleImplementationsForm.RadioButton1Click(Sender: TObject);
begin
  CurrentCard := ServiceLocator.GetService<ICreditCard>('VISA');
end;

procedure TMultipleImplementationsForm.RadioButton2Click(Sender: TObject);
begin
  CurrentCard := ServiceLocator.GetService<ICreditCard>('MasterCard');
end;

procedure TMultipleImplementationsForm.RadioButton3Click(Sender: TObject);
begin
  CurrentCard := ServiceLocator.GetService<ICreditCard>('Discover');
end;

procedure TMultipleImplementationsForm.RadioButton4Click(Sender: TObject);
begin
  CurrentCard := ServiceLocator.GetService<ICreditCard>('AMEX');
end;

The above code will assign an instance of the appropriate implementing object to the single variable CurrentCard depending on which radio button the user selects.  The proper object is returned based upon the string parameter passed to the GetService call.  That string value, of course, corresponds to the object registered with that same string as shown above. 

Thus, you can register by name and then use as many implementing objects for a single interface as you want.   This is obviously very powerful, as you can choose from any number of implementations as well as add new implementations anytime you want.

A sample application showing this technique as well as some other interesting features can be found in the samples that come along with the Delphi Spring Framework

Fun Code of the Week #2

By Nick at November 07, 2011 15:51
Filed Under: Delphi, Fun Code, Software Development
function RandomString(aLength: Integer; aInputChars: string): string;
begin
  Result := '';
  if Length(aInputChars) <= 0 then
  begin
    Exit;
  end;
  Randomize;

  repeat
    Result := Result + aInputChars[Random(Length(aInputChars)) + 1];
  until (Length(Result) = aLength);
end;

Getting Giddy with Dependency Injection and Delphi Spring #8 – Miscellanea

By Nick at November 05, 2011 14:03
Filed Under: Delphi, Software Development

So far I’ve covered a much of the basics of Dependency Injection.  There’s a lot more to it, and plenty more to discuss, but for this article, I want to stop and discuss a few items that I have kind of glossed over.  So without further ado, here they are in my beloved bullet form:

  • I have been, as you’ve likely noticed, encouraging you to use interfaces when coding, and registering classes as implementing those interfaces with the framework.  What I think I failed to mention explicitly is that all interfaces registered with the Spring Framework have to have a GUID associated with them.  You can add a GUID any time you want into your code by pressing CTRL+SHIFT+G.  If you try to use an interface that doesn’t have a GUID, you’ll get this error:  “Project <projectname>.exe raised exception class ERegistrationException with message 'Non-Guid Interface Services are not supported.
  • If you’ve looked closely at the code in the demos, you might have noticed that before you can do anything with the Spring Container, you need to call GlobalContainer.Build;  This method needs to be called before you can get anything out of the ServiceLocator.  The Build method is the code that gathers up all the registered classes and either creates them or enable them to be created on demand, depending on the lifetime type that you have selected.  If you get the error 'LifetimeTypeManager was expected.' when you run your app, it likely means that you have faced to call Build on your container.  And in fact, the Build method is really the main purpose of your DI Container.  You should call Build once, and at the root of your application.  For Delphi developers, this means that it probably ought to be called as one of the very first things in the DPR file. This also means that you need to register your classes as early as possible as well.
  • You don’t have to use the Global Container and the Service Locator provided by the framework.  You are more than welcome to create your own and expose the functionality as you want.  What we have done here at Gateway Ticketing is to declare an interface that is a complete abstraction of the notion of a DI Container, and then implement the interface ourselves using a TContainer descendant from the Delphi Spring Framework.  That way, if the framework changes (and it has since we started) or if we even decide to use a different container, our code is completely decoupled from any particular implementation.  Just another great example of “Code against abstractions, not implementations.” Smile
  • I feel compelled to point out that the whole concept of a Service Locator is considered an “anti-pattern” by some. I haven’t come to a firm conclusion on this issue myself.  Yes, a Service Locator is almost always a Singleton, but I personally don’t view read-only singletons to be bad as do some.  (A read-write singleton is really a global variable, and I think we can all agree that global variables are the Spawn of Satan.) However, there appears to be some dispute as to whether the use of a container is indeed a Service Locator. Also, if all of your dependencies are defined before execution is available to the user, then is a Container really a variable at all?  It remains a matter of debate. Ultimately, I guess I view a Service Locator as so valuable and useful so as to out-weigh any of the drawbacks they might have. 
  • There is a weakness here -- and which gets to the previous point – in that things are actually so decoupled and late-binding is so explicit that it is indeed possible to get a successful build and not know that you forgot to register a needed implementing class until runtime.  And, in a complex system, it might be a long time before anyone notices that the implementing class for a seldom used interface is missing.  If you follow the pattern that I have shown of registering an implementation in the initialization section of a unit, then you must use that unit somewhere in your app to actually have the registration take place. And as mentioned, if you forget to add it, and don’t actually include that unit in your app, the compiler won’t tell you and you will only find out at runtime.  This is a weakness and you need to be very careful to ensure that you don’t fall into this trap.  Strategies might include a single unit for doing all of your registration, or some type of static analysis that ensures that every call to GetService has a corresponding RegisterService call (or whatever your methods are called).  Something to be aware of.

Those are just a few things that you might want to consider as you integrate Dependency Injection into your coding techniques. I’ve said it before, and I’ll say it again:  If you aren’t doing Dependency Injection, you're doing it wrong. 

Flotsam and Jetsam #48

By Nick at October 29, 2011 19:51
Filed Under: Delphi, Flotsam and Jetsam

Flotsam and Jetsam #47

By Nick at October 18, 2011 12:52
Filed Under: Delphi, Flotsam and Jetsam

Delphi Mocks: The Basics

By Nick at October 16, 2011 21:41
Filed Under: Software Development, Delphi, Unit Testing

Introduction

As you may have noticed, I’ve kind of started to become a championship caliber pain in the butt about unit testing.  I walk the halls of Gateway Ticketing saying “If your code isn’t easy to test, you are doing it wrong”.  I keep giving my Unit Testing presentation to anyone that will listen.  But I feel justified – unit testing is critical to writing clean, maintainable code.

One of the reasons people seem to frequently give for not doing unit testing is that “My code requires <some external dependency> and it’s too hard to configure for simple unit tests” or something like that.  Okay, fair enough.  I won’t point out how you should be using Dependency Injection to decouple that code and enable you to insert a mock or a stub or a different class for testing purposes.  (Okay, I lied – technically I guess I did mention that.  Sorry.)  But I get that sometimes implementing a complete, formal TMockXXXX version of your interface (and you are coding against interfaces and not implementations, right?) is not something you want to do. 

Mocks

In their simplest form, a mock object is simply an alternate implementation of a class that provides “fake” responses to method calls.  For example, you have a class TCustomer that has a method GetCustomerName, and normally, that call goes to the production database and gets the name (a simple, unlikely example, I know, but you get the idea).  So to avoid the call to the database, you just create TMockCustomer, and implement it’s call to GetCustomerName and have it return “George Jetson” every time.  This enables you to test the class that is using TCustomer without having to hit the database at all.

But that can get a bit clumsy.  What if you want to return different values based on different inputs?  What if you find a bug based on specific input or output, and you want to create a unit test for that specific case?  Then a mock class as described above gets harried, complicated, and hard to maintain.

Enter a Mocking Framework

What if we could have a framework that would allow us to implement any interface, and define easily and exactly what the inputs and outputs should be?  That would be cool.  This would enable you to easily create a mock object that can respond to method calls in defined ways in a flexible, easy to set up manner.  This is what a mocking framework does.

Obviously something this flexible needs some powerful language features.  Such a framework would have to be able to flex to dynamically implement an interface.  It would have to be able to dynamically recognize method calls and respond accordingly.  Fortunately, Delphi XE2 is up to the task.  Delphi XE2 introduces the TVirtualInterface class that lets you dynamically implement any interface at runtime.  Combine that with the new RTTI, and you have the ability to build a very powerful mocking framework.

And that is just what Vince Parrett of VSoft Technologies, author of the wonderful FinalBuilder, did.  He has built a very cool and very powerful library called Delphi Mocks and released it as open source for all of us.  Very cool – thanks, Vince.   Delphi Mocks is available on GitHub under the very developer friendly Apache 2.0 License.  Vince has written a nice “Getting Started” guide, but I wanted to write  this article to build a very simple example of a pretty simple use case for mock objects.  So let’s do that.

An Expensive Service

A typical use case for using a mock object is to replace a service that is “expensive”.  Sometimes that means expensive as in “actually costs money”, but it will more likely mean expensive in CPU cycles, database connectivity, or anything else that requires an external dependency that causes your class under test to stop being tested in isolation and start being integrated with something else.   Since a unit test should always test something atomically and leave nothing (database entries, files, charges on a credit card) lying around, any time that will happen when running a unit test, you probably should consider a stub or a mock object instead.

By “stub” I mean “a class that implements a particular interface but doesn’t really do anything”.  It’s not exactly the same as a mock object in that the interface in question will normally not return anything but merely do things external to the class.  A typical example is a logging class.  If you are running unit tests, you don’t want your logging system writing logs all over the place every time you run your tests, so you create a Logger stub class that acts like your regular logger, but which actually doesn’t do anything.  You can call it in your code, but you get nothing from it – which is what you want. 

So let’s look at a simple, but “expensive” service.  Consider the following code:

unit uCreditCardValidator;

interface

uses
      SysUtils;

type

  ICreditCardValidator = interface(IInvokable)
  ['{68553321-248C-4FD4-9881-C6B6B92B95AD}']
    function IsCreditCardValid(aCreditCardNumber: string): Boolean;
    procedure DoNotCallThisEver;
  end;

  TCreditCardValidator = class(TInterfacedObject, ICreditCardValidator)
    function IsCreditCardValid(aCreditCardNumber: string): Boolean;
    procedure DoNotCallThisEver;
  end;

implementation

uses
     Dialogs;

{ TAdder }

function TCreditCardValidator.IsCreditCardValid(aCreditCardNumber: string): Boolean;
begin
  // Let's pretend this calls a SOAP server that charges $0.25 everytim
  // you use it.

  // For Demo purposes, we'll have the card be invalid if it the number 7 in it
  Result := Pos('7', aCreditCardNumber) <= 0;

  ShowMessage('You were just charged $0.25');
end;

procedure TCreditCardValidator.DoNotCallThisEver;
begin
  // This one will charge the company $500!  We should never
  // call this!
end;

end.

This unit declares two things, an ICreditCardValidator and a class that implements it, TCreditCardValidator.  It simulates deciding a credit card is bad by saying any card number that has the number ‘7’ in it is bad.  Otherwise, any string will be acceptable. It’s a demo class, obviously, but it illustrates a class that would be used only in production, as you get charged by a credit card validating service every time you call IsCreditCardValid.    Clearly, you don’t want to be calling that whenever you run your tests.  Thus, it seems likely that any collection of unit tests that wants to use this service would likely want to use a mock class.

A Class to Use the ICreditCardValidator

Mock classes really become useful when you are testing a class that consumes an expensive service.  Thus, we’ll declare the following class, TCreditCardManager, which consumes ICreditCardValidator:

unit uCreditCardManager;

interface

uses
      uCreditCardValidator
    ;

type
  TCreditCardManager = class
  private
    FCCValidator: ICreditCardValidator;
  public
    constructor Create(aCCValidator: ICreditCardValidator);
    function CreditCardIsValid(aCCString: string): Boolean;
  end;

implementation

{ TAddingMachine }

function TCreditCardManager.CreditCardIsValid(aCCString: string): Boolean;
begin
  Result := FCCValidator.IsCreditCardValid(aCCString);
end;

constructor TCreditCardManager.Create(aCCValidator: ICreditCardValidator);
begin
  inherited Create;
  FCCValidator := aCCValidator;
end;

end.

This class is really simple – it just takes an ICreditCardValidator in it’s constructor and uses it to validate credit cards.  As a demo class it is really simple, but a more complete class would have methods to make payments against the card, etc.  But if, when testing this class, you pass it in an implementation of the ICreditCardValidator above, you’ll get charged $0.25 for every test you run.  That’s not something you’d really want to do, so this class seems like a good candidate for using a mock object to replace the implementation of ICreditCardValidator

Testing TCreditCardManager Can Be Expensive

So, the typical way to test TCreditCardManager might look like this:

procedure TestTCCValidator.TestValidateCreditCard;
var
  ReturnValue: Boolean;
  ExpensiveCCValidator: ICreditCardValidator;
  ValidCard: string;
  BadCard: string;
begin
  ExpensiveCCValidator := TCreditCardValidator.Create;
  FCCValidator := TCreditCardManager.Create(ExpensiveCCValidator);

  ValidCard := '1112221'; // Rule is that a bad card has a '7' in it
  BadCard   := '6667666'; // ..so this one is bad

  ReturnValue := FCCValidator.CreditCardIsValid(ValidCard);
  CheckTrue(ReturnValue);

  ReturnValue := FCCValidator.CreditCardIsValid(BadCard);
  CheckFalse(ReturnValue);
end;

However, if you run this in the GUI test runner for DUnit, you’ll see this:

image

 

And of course, if you keep this up, the bill you get will not make your boss happy.

Testing with a Mock

So, to avoid the wrath of your boss, you should create a mock object that behaves like you want it to but that doesn’t end up costing anything.  The first way you might do it is to create a new class that implements the ICreditCardValidator interface, but that does nothing or returns set values.  But that is kind of clunky, and hard to customize.  What you really want is what I mentioned earlier, an extensible mock that can be created an configured on the fly.  That’s where Delphi Mocks comes in.

The Delphi.Mocks.pas unit declares a type TMock which takes a parameterized type, and which then can sort of morph itself into an implementation of that interface using the cool new-to-XE2 class called TVirtualInterfaceTVirtualInterface basically allows you to implement an interface on the fly at runtime.  Thus, you can create a generic class (or record, in the case of TMock) that can appear to be any interface you want it to be. 

Thus, we can create a TMock that looks and acts like an ICreditCardValidator:

var
  CCMock: TMock<ICreditCardValidator>;
 begin
  CCMock := TMock<ICreditCardValidator>.Create;
  ...
end;

Once we have that mock, we can tell it how to behave:

  ValidCard := '1112221'; // Rule is that a bad card has a '7' in it
  BadCard   := '6667666'; // ..so this one is bad

  CCMock.Setup.WillReturn(True).When.IsCreditCardValid(ValidCard);
  CCMock.Setup.WillReturn(False).When.IsCreditCardValid(BadCard);

This code uses a nice fluent interface to be somewhat self-explanatory.  It basically sets the mock up as follows: “When I pass in the valid string, return True.  When I pass in the bad string, return False.”  This is a basic definition that will allow your TCreditCardManager class to exercise itself with both good and bad input, allowing you to test your code with both kinds of responses.  We can determine exactly what the inputs and outputs are and ensure that the mock displays the correct behavior and follows the business rules set out in the “real” implementation.  Notice, too, that the When call, through the delightful magic of generics, is actually an implementation of the ICreditCardValidator interface, and thus is able to execute a real method call to the method from that interface.  You even get support from Code Completion in the IDE. 

Now, you can create the Credit Card Manager, pass it your mock object, and run tests with your mock input and output:

  FCCValidator := TCreditCardManager.Create(CCMock);

  ReturnValue := FCCValidator.CreditCardIsValid(ValidCard);
  CheckTrue(ReturnValue);

  ReturnValue := FCCValidator.CreditCardIsValid(BadCard);
  CheckFalse(ReturnValue);

This way, you can exercise the instance and test it  to your hearts content without incurring any of the expense associated with your “regular” implementation.  If you need to add additional tests, you can simply tell the mock class what the new input and outputs are, and then run the appropriate tests.

Ensuring Code Is (or Is Not) Called

When writing tests, there may be times when you want to ensure that a given method is called with a frequency that you want to specify.  Thus, you can write things like:

  CCMock.Setup.Expect.AtLeastOnce.When.IsCreditCardValid(ValidCard);

  // Ensure that the tests never call this.  It costs $500!!
  CCMock.Setup.Expect.Never.When.DoNotCallThisEver;

And then, when all the test are run, call:

CCMock.Verify;

on the mock object, and it will validate that the calls that you required were indeed called. 

So, in the above example, if I were to call:

CCMock.Instance.DoNotCallThisEver;

I would get the following dialog:

image

…which of course tells me that I called a method in my tests that should not have ever been called.

There are also methods on the call to Expect interface that ensure that a certain call is made a minimum or maximum number of times, between a specified  number of times, at least or at most a certain number of times, and as we saw, even never.  Also, you can specify that one method be called before or after other methods.  This enables you to dictate exactly how your object methods are called, and what should or should not happen when you run your tests.

Conclusion

So the Delphi Mock library is a very powerful tool for making it easy to write concise unit tests that don’t connect to “expensive” classes that could make testing difficult.  The goal of writing testable code is a worthy one, and Delphi Mocks definitely can make it easier to reach that goal.

Getting Giddy with Dependency Injection and Delphi Spring #7 – Controlling Construction

By Nick at October 08, 2011 21:47
Filed Under: Software Development, Delphi

As always, you can download the Delphi Spring Framework from GoogleCode.

By now you should be getting the idea about dependency injection – how you can use it to decouple your code and provide instances of your objects.  Hopefully you see the benefits of coding against interfaces and not implementations.  And if things are going really well, you are writing unit tests with ease because your code is easily tested. 

However, I bet by now some of you are thinking that this looks really cool and all, but there is just a touch too much “magic” going on – that there is a bit too much going on under the covers.

Well, you are right about that – there is a lot going on under the covers.  The Delphi Spring Framework does a lot of work for you, mainly by creating instances of classes using Run-time Type Information (RTTI).  It controls the creation, and can even let you manage the lifetime of those objects.

But I also bet that some of you are a bit uncomfortable with the notion of relying on all that magic.  While turning over that control will work in many cases, you don’t always want to give up control over the  creation of your objects. 

Well, you don’t have to.  The framework allows you to customize the way that your classes are created if you so desire.  Very often, if your classes are well designed – your constructors are simple, you aren’t doing much more than assigning values – you don’t need to do anything special when you construct an instance.  But sometimes you do.  Sometimes, your class needs to be passed something dynamic – a class whose state can only be known at runtime.    For instance, you may have a given customer, and that customer has invoices, and you have a class that you want to pass that customer to, but you also want to completely decouple that class.  Your customer is dynamic – you may be running a query and need to perform this operation on every customer in your database. Or maybe the customer is doing something on your website, and so your customer object is specific to that customer.  In any event, the customer data is dynamic at runtime, and so the creation of an object can’t be cookie-cutter.  It has to be unique each time you need an instance of this object that takes action on the given customer. 

The code below comes from the Samples directory of the Delphi Spring Framework.  It’s part of the Demo.Spring.DelegatedConstructor project

The Spring Framework lets you control the creation of your objects through a method on the TRegistration class – the class used to register types against interfaces.  As part of registering your class, you can pass an anonymous method of type TActivatorDelegate, which his declared as:

TActivatorDelegate<T: class> = reference to function: T;

The TRegistration class uses the fluent interface, so you can chain together a number of things that you want to attach to any given registration.  So, for instance, if you have a project involving a TUser class, and the TUser class is dynamic, then a class (such as TUpgradeUser) which needs a TUser, might be registered as follows:

  GlobalContainer.RegisterType<TUserProcessor>.Implements<IUserUpgrader>.AsTransient.DelegateTo(
    function: TUserProcessor
    begin
      Result := TUserProcessor.Create(GetCurrentUser);
    end
  );

The TUserProcessor class is registered as implementing the IUserUpgrader interface.  The lifetime of the resulting class is set to be “Transient” meaning that the implementing class will live “normally”; that is, it will be destroyed when the interface reference goes out of scope.  (Note that AsTransient is the default lifetime.  We’ll discuss container lifetime management in a future blog post). 

Finally, the actual creation of the TUserProcessor class is “delegated to” an anonymous method – a function in this case, as noted above – that simply returns an instance of the TUserProcessor class.  The key here, of course, is that the anonymous method can call the GetCurrentUser routine which will inject the current, dynamic TUser instance into the resulting object.  You can do anything you want in this anonymous method, including creating and setting up the resulting object in any manner you choose.  You could set properties and even call methods on the resulting, implementing object. 

If you examine the code for the project, you’ll note, of course, that it doesn’t actually do anything other than write to the console.  The GetCurrentUser call is merely a singleton returning the same instance of TUser.   The code is merely illustrative, and so the “background stuff” doesn’t really do anything.  In a real application, a call to GetCurrentUser would do just that, return an instance of TUser that represented the current, dynamic state of the user in question.   The critical part to note is that you can control the creation of the TUserProcessor to as large a degree as you want. 

Finally, when you actually call the ServiceLocator to grab an instance, the Container will call your anonymous method and return an instance constructed exactly like you want it to be constructed.

So in the end, the Spring Container gives you total control – if you want it – over the creation of your objects.  If you need to, you can have a little control over the “magic” that takes place and sprinkle your own little fairy dust on the construction process.

Fun Code of the Week #1

By Nick at October 06, 2011 20:20
Filed Under: Delphi, Fun Code
unit uIsPalindrome;

interface

function IsPalindrome(const aString: string): Boolean;

implementation

uses
       Spring.Collections
     , {$IF CompilerVersion >= 230}System.{$IFEND}SysUtils
     ;

function CleanString(const aString: string): string;
var
  C: char;
begin
  // Remove all non-alpha chars and make all lower case
  // Spaces don't matter, so let's count only letters
  Result := '';
  for C in LowerCase(aString) do
  begin
    if CharInSet(C, ['a'..'z', 'A'..'Z']) then
    begin
      Result := Result + C;
    end;
  end;
end;

function IsPalindrome(const aString: string): Boolean;
var
  Stack: IStack<Char>;
  C: Char;
  NoSpaces: string;
  Temp: string;
begin
  NoSpaces :=  CleanString(aString);

  Stack := TCollections.CreateStack<Char>;
  for C in NoSpaces do
  begin
    Stack.Push(C);
  end;
  Temp := '';
  repeat
    Temp := Temp + Stack.Pop;
  until Stack.Count = 0;
  Result := Temp = NoSpaces;
end;

end.

Added: I always enjoy posting code like this. Note that it is entitled "Fun Code", not "Highly optimized, perfectly written Code". ;-)

Flotsam and Jetsam #46

By Nick at October 05, 2011 22:58
Filed Under: Delphi, Flotsam and Jetsam
  • I will be speaking this year at CodeRage 6.  I’m giving two talks, one on Dependency Injection, and one on Unit Testing.  Please attend.  I think my talks in particular will be really good.  But maybe not as good as all the other stuff you can learn there
  • Are you aware of the fact that FireMonkey, RAD Studio, and Delphi all have spanking new pages on Facebook?  I wasn’t.  And they do.
  • Holy crap!  Allen Bauer is alive!
  • I’ve been trying to write some more example applications for the Delphi Spring Framework, and so I was researching the Factory Pattern to see if I could find a good illustration to build an example for (TFoo and TBar can only take you so far….) and I ran across a nice article on MSDN that describes it nicely.  It actually has a nice example of a “Computer Factory”, and I’ll likely riff of that to create a “real world” example of a physical object.  But the part that caught my notice, and caused me to write this entry was a quote at the beginning:  “When was the last time someone asked the designers of the Empire State building to add ten new floors at the bottom, put a pool on the top, and have all of this done before Monday morning?” And the answer, of course, is “never”.  Winking smile  Anyway, it just was another data point in my ongoing contention that software developers are not engineers. 
  • This is a pretty amazing and thorough tutorial on LiveBindings.  Live Bindings is one of those cool features that I need to learn about and that appears to be cool now, with the potential to get a lot cooler in the future.

Flotsam and Jetsam #45

By Nick at September 29, 2011 14:04
Filed Under: Flotsam and Jetsam, Delphi
  • One of the cooler – but unsung – features of Delphi XE2 is the fact that it includes an ODBC Driver for dbExpress.  Do folks realize this basically means that Delphi can now use all its cool Delphi goodness with just about any database backend?  Everyone has an ODBC driver, and so now you can connect anywhere you want with dbExpress and Delphi.  Like I said, a pretty good little feature.
  • I have just checked in a number of sample applications that illustrate how to use various features of the Delphi Spring Framework.  It is far from complete, and I will be adding more demos, writing articles about each demo, and trying to comment the code.  In addition, I’ll be working on fleshing out the documentation and the wiki that are part of the Google project as well as continuing my blog series.  This is really proving to be a lot of fun for me, and I’m glad to be able to make a contribution to the community. 
  • I asked this on Twitter and got a few responses and a little info.  Does anyone out there know what is up with the DUnit project?  It looks like Mark Edington of Embarcadero is a committer and has made some changes in the past few months, but it seems to me that given the new capabilities of Delphi (Generics, anonymous methods, attributes, etc), this project is screaming out for someone to take it to the next level.  Anyone interested?  How do we make that happen? This needs to happen.
  • More from the “You learn something new every day” category:  you can tag a unit with “experimental” and the compiler will issue a warning.   Example: unit Spring.Configuration experimental; will issue the warning [DCC Warning] Spring.Core.dpk(80): W1007 Unit 'Spring.Configuration' is experimental Haven’t seen that one before, I must confess.
  • Roman Kassebaum is at it again.  He’s updated the Orpheus project on SourceForge to work with Delphi XE2 and XE2/64-bit. Very cool. And while he was at it, he’s updated the PowerPDF project as well.  Thanks Roman.

Revenue Recognition and the Software Development Industry

By Nick at September 29, 2011 00:10
Filed Under: Delphi, General, Software Development, TechBiz

Before I start, I want to stress that I am not a lawyer.  I am not an accountant.  You’d be a total fool to base any business or legal decisions on anything I write here.  Consult a an attorney or a fully accredited CPA or some other person who truly knows what he’s talking about before deciding how to make any decisions whatsoever about anything having to do with money, the law, revenue, etc.  I don’t know anything, and if you listen to me, you are making a big mistake. 

Introduction

Developers and other people involved in the software business have heard a lot about “Sarbannes-Oxley” (SOX) and “revenue recognition” and how it effects what Embarcadero can and cannot do with respect to updates, upsells, promotions, and all kinds of issues surrounding selling and releasing Delphi.  SOX was a significant, game-changing piece of legislation here in the US, and it affects virtually every public company in the country.  It also affects private companies that might someday want to be a public company.  It affects software companies in particular, because software is not a physical good in reality, but “acts” like one in the marketplace. 

When I was at Borland/CodeGear/Embarcadero, it took me a while to come to grips with what SOX meant and how it altered our business and what we wanted to do.  Frankly, I found it all very frustrating.  On the face of it, the rules and limitations seemed ridiculous. At first I complained bitterly about it.  It took a while, but finally I came to accept them and realize that SOX and the ensuing rules were the “field we had to play on”.  Finally, I think I actually gained enough insight into it that I was able to come to grips with the new rules and understand why things work the way they do.  As a result, I thought I’d share a bit of that with you fine people.

What is Revenue Recognition?

First, it might be obvious, but let’s be sure we know what the term “revenue recognition” means.  Revenue recognition is the process by which a business says “Yep, we actually earned that revenue”.  Note, it most decidedly does not mean “We got the cash”.  In an accrual accounting system – common to businesses of almost any size – the receipt of cash can actually go down as a liability. Think of taking an advanced payment for services: If you take half the money up front for a job, you have it in the bank, but you still owe the services. Revenue can’t be “recognized” until you do in fact deliver that good or service for the money you’ve received.  So if you are a software company, you can recognize revenue only when the software you sell is actually delivered. But software is a strange product in this regard, as we’ll see. As a result, The rules for  revenue recognition for software are somewhat cloudy and definitely untested in a court of law.

Why it Became an Issue

When it comes to software, one of the main roots of the revenue recognition rules stem from the (previously) common practice of "pumping the channel".  Near the end of the quarter, firms would "sell" lots of stuff to their channel partners.  For example, lets say that there was a software company called TrollWare.  Selling for a given business quarter started looking a little thin, so TrollWare would "sell" $1,000,000 of product to their favorite online/catalog retailer.  (And remember, this was actual, physical boxes back in the day.)  Then, they'd claim $1,000,000 of revenue on their books.  Wall Street, creditors, and anyone else interested in a company's revenue would think "Hmmm -- that's $1,000,000 in revenue more than we thought!  Buy TrollWare stock!” Obviously, this wasn’t a real sale, and could actually end up being a net cost because of the need to actually ship (and maybe even actually destroy) physical boxes of software.  This was a common practice throughout the industry, and many companies that we have all heard of did this.

Of course, most often, TrollWare would only really sell, say, $100,000 of all of that "shipped" software by the end of the month and have to buy back $900,000 of it at some point, but hey, revenue is revenue!  Clearly this is not a practice laced with clarity, openness, and integrity with respect to people looking at the viability of Trollware.

New, Tougher Rules

This kind of thing was one of many reasons that prompted passing of SOX.  The results of SOX are varied, but the results of interest to us software developers were new Generally Accepted Accounting Principles (GAAP) rules for software companies that defined revenue as truly delivering something to the customer.  Now, for a hot dog company, it's pretty clear when a box of hot dogs has been fully manufactured and when that box has left the warehouse on the way to a consumer or a business, or whomever is the "end user" of those hot dogs.  For example, if you are a rake manufacturer and sell rakes to Home Depot, you can claim the revenue when the delivery truck leaves your loading dock heading to that big orange building.  Retailers of rakes like Home Depot can claim the revenue when the rake is scanned across the Point of Sale on its way to clear someone’s lawn.  In the first case, Home Depot is the "end user" and in the second case, the guy with the leaves on his lawn is.

But then the question becomes:  What does it mean to "deliver a completed software product to the end user"?  Well, that's tricky.  There are two things here, of course.  First, when is the product really “completely produced and manufactured”.  Is a beta good enough?  What if a promised feature isn’t quite finished? How about a feature that was promised but isn’t there at all? Second --  assuming that you can define the first item -- when is that completed software product actually delivered? Who *really* is the end user?  As it turns out, it’s not quite analogous to the rake manufacturer/Home Depot relationship described above.  Because software companies were actually fairly guilty of the dubious “channel pumping” practices described above, the rules about what constitutes “final delivery” of software are fairly restrictive, and certainly different than those dictating gardening tools.

There is a lot of accounting literature about this (I’m not thrilled about the fact that I've read a lot of it.  It’s not exactly scintillating).  For instance, do a Google search on “revenue recognition software licenses”  and start reading.   The rules are pretty complicated and hard to qualify exactly. And further complicating things, no software company has yet been brave enough to test these rules in court, so they are even murkier as companies work hard to stay well away from the borders of where the rules end and a call from the US Department of Justice starts. 

Thus, software revenue can only be recognized when said software is fully and completely delivered to the end user.  For a "normal" sale like most of us think of it, revenue can be recognized when the end user has the ability to install the software -- a license is delivered and the user installs it.  (For physical software, it's still the truck leaving the loading dock to the actual end user  and not merely the reseller). 

There's a catch, though:  It has to be the complete, finished package.  As mentioned above, revenue can only be recognized when a completed product is delivered.   If you deliver a "preview" of your product or even a feature of your product, this can imply a commitment to deliver something at a later date.  If you even implicitly promise that the purchase today will result in a delivery later, then that probably means you can't recognize revenue until that implicit promise is met.  Again, I say “probably” because this is turning out to be the common interpretation of the rules in a world where no one wants to test this in court.  This is a unique problem for software because no one normally buys a “preview lawn mower” with the promise of more functionality later.

An Example

So, for example: Troll Software delivers a Trollware 1.0 in mid-February.  Their spell checker isn't really quite ready, but they need to ship because their main competitor has already shipped a version with a spell checker. Or maybe the need to get some Q1 revenue to keep from not making any money and having to to massive layoffs is a driving factor in the decision.  So they ship the product with the label "Spell Checker!!! (Preview only)”.   Then, a week into April, they deliver their fully ready Spell Checker to all existing purchasers and update their downloadable ZIP file.

They sell $1,000,000 worth of Trollware by March 31, and think "Yay! We have $1,000,000 in revenue in Q1! Wall Street will love us!"

Oops, not really:  They actually have $0 of revenue in Q1 from Trollware.  That’s right:  $0 in revenue. All of those sales become Q2 revenue, because they didn't actually complete the delivery of any Trollware versions in Q1, but instead in Q2.(This brings about the interesting situation where a company can have $1,000,000 in the bank and $0 of revenue on 31 March for Q1).

Another example:  Say you are a Trollware subscriber, and sent them $1200 a year as part of your subscription, receiving updates, improvements, and new features during the term of the subscription.  Troll Software can only recognize $100 a month for the 12 month term of the subscription.  And consider this:  What iff Troll Software wanted to move exclusively to subscription model starting the first of the year?  They might have the same number of customers buying, but now their revenue for the first month would immediately be 1/12 of what it normally is, despite having a lot of money in the bank as noted above. 

Bug fixes to existing functionality is actually excluded from this -- this is why you normally don't see new features in bug fix updates.

The same might go for "Special offers to registered users".  Say they sell a bunch of Trollware in the first half of the year.  Starting July 1, they say "Free Grammar Checker to anyone that buys Trollware 1.0!" and in the small print it says "... and if you already have Trollware 1.0, you can have the Grammar Checker, too".

Well, now, if this is the case, have you actually delivered the software to the buyers who purchased before the special offer?

That's why I said "might".  As I understand it, this particular issue isn't exactly clear and hasn't been tested in court as far as I know.  And of course, no one wants to be the test case for the SEC or the Department of Justice.  So in the end, it seems that no one is willing to risk such a deal.

Revenue is King

And of course revenue is everything in business and finance, because it represents the value that you have actually delivered to customers.  Revenue is the only real way to measure the accomplishment of a company.  And that's fair if you think about it -- that is where Enron is a great example.  They weren't actually delivering anything to end customers, but still racking up revenues like crazy.  So in the end, measuring accurately what is really, no kidding delivered to end users is what finance people are interested in knowing.

Sarbannes-Oxley was sort of the root of this.  One of its main features was to actually hold the corporate officers of public companies criminally liable for their GAAP compliance.  The threat of prison time has a tendency to focus the senses.  As a side result of SOX, the definition of revenue recognition – and more importantly the desire to strictly follow that definition -- really became an issue, and the need to know a companies real revenue was one of the main fallouts.  CEO’s wanted to be 100% sure that they were recognizing revenue correctly because, well, they don’t want to go to jail.  Now, there is a lot not to like in SOX, and I personally would like to see it repealed, but the end result being that software company CEOs became far more focused on correctly recognizing software revenue.  It's still a bit unclear, and the software industry is still very wary of all of it, because it is untested in court, and as I said, no one wants to draw the attention of the US Government on the matter. 

In the end…

Every public company that produces or sells software has to follow the rules set up by SOX.   Any business that wants to get a loan from a bank or otherwise interact in the general community of businesses needs to follow GAAP.  It's not always  fun, but that is the way it works.  These revenue recognition rules can result in companies having to do some strange things and, more importantly, not being able to do things that they might want to do and which might even make good sense.  But in the end, all organizations in the software business have to follow these rules. 

However, in the end, I have no problem with their being clear, concise rules about what "revenue" really means.  Really, I think it is hard to disagree.  Revenue is a measure of actual, delivered value, and thus a measure of the real value provided by a corporation.  That's something that is really good to know.

Getting Giddy with Dependency Injection and Delphi Spring #6 – Don’t even have a constructor

By Nick at September 24, 2011 13:54
Filed Under: Delphi, Software Development

Introduction

Article Four in the series had a couple of rules to follow, one of which was “Keep Constructors Simple”.  In the last article we saw how you can use the Spring Container to hold interfaces with specific implementations so that you don’t have to create anything, but instead ask the container for an instance of an interface. 

Well, in this article, I’m going to go a step beyond even that, and show you how the Delphi Spring Framework can make it so that you don’t even need to have a constructor by automatically injecting implementation instances when they are needed without you having to do a thing. 

A Side Note

In the previous article, I had you create a unit called uServiceLocator.pas that provided a central location for registering and resolving interface implementations. Since then, the Spring codebase has changed to provide a similar functionality.  The Spring.Services unit contains a singleton function ServiceLocator that is used for getting services (and indeed the call has changed from Resolve to GetService).  The Spring.Container unit contains a similar function GlobalContainer that is used to register the interface/implementation combinations.  All items registered into GlobalContainer are available for retrieval via ServiceLocator

A Little Review

One of the common things that happen in a constructor is the creation of other needed things.  In the past few articles, we’ve talked about the need to reduce dependencies by not creating things you need but instead asking for them in your constructor.  The reason that you don’t want to do much at all in a constructor – why you want to pass stuff in to it instead of actually creating things – is to limit what happens when you do create objects.  Consider this code:

constructor TOrderProcessor.Create;
begin
  FOrderValidator := TOrderValidator.Create;
  FOrderEntry := TOrderEntry.Create;
end;

This code looks pretty normal – you are creating some instances of classes you need to process an order.  But there are a couple of problems here that need to be avoided:

  • You are stuck with TOrderValidator.  That’s the only class that TOrderProcessor can use.  You can’t choose to use a different class or implementation.  That’s it. Same for TOrderEntry.
  • Not only are you stuck, but you are coupled to it.  If TOrderValidator changes in ways that you don’t like, you might never know.  Because you are using the unit that it is declared in, you might get careless and start calling other stuff in that unit.  Pretty soon and before you know it, your code is hopelessly joined to those other classes in ways that  may make it difficult or impossible to disentangle.  And being tangled up with another class is bad.
  • There is no way of knowing what a TOrderValidator does, creates, or otherwise allocates.  It could be in and of itself creating thirteen other classes, allocating huge blocks of memory, accessing a database or even firing up a nuclear weapon.  Who knows?  The downstream effects of merely creating TOrderProcessor class can be pretty much something out of your control  And it could change as other parts of the code is worked on by other team members. 
  • Along those same lines, you don’t know what will be left around after you use these classes. They might write records to a production database. TOrderValidator might go off and incur a charge of $0.50 at your credit card validating company.  (Imagine your boss getting that bill after you run your unit tests with this code a couple of thousand times….)  In the end, you are tightly coupled to those classes.  That is bad.

So we could use the Spring Container to have it so that we don’t even have to call Create on the helper classes:

procedure DoOrderProcessing;
var
  Order: TOrder;
  OrderProcessor: IOrderProcessor;

  OrderValidator: IOrderValidator;
  OrderEntry: IOrderEntry;
begin
  GlobalContainer.Build;
  Order := TOrder.Create;
  try
    OrderValidator := ServiceLocator.GetService<IOrderValidator>;
    OrderEntry := ServiceLocator.GetService<IOrderEntry>;
    OrderProcessor := TOrderProcessor.Create(OrderValidator, OrderEntry);
    if OrderProcessor.ProcessOrder(Order) then
    begin
      WriteLn('Order successfully processed....');
    end;
  finally
    Order.Free;
  end;
end;

 

Note that we are still calling Create on the TOrderProcessor itself, but we’ll show how to tell the Container exactly how to create our class in the next article.

So in this way, we are able to completely decouple the classes from each other, and we are able to ask the container for implementations.  Thus, if we wanted to, say, implement mock objects for these interfaces, we could easily do this by simply choosing to register mock classes against those interfaces instead of “real” classes.

Never Call Create

But  if we have to have to be really careful about not doing too much stuff in a constructor, how about just not having a constructor at all?  How about if we had a way of initializing everything that needs initializing while merely relying on the default constructor from TObject?  Impossible you say?  To that I say – bah!  Let’s do it! 

I should note that often a class’s constructor will require other assignments to integers, strings, and other non-class types.  That will, of course, require a constructor, but the point here is to illustrate that you can decouple your classes so much that you don’t even have to create them.

Getting Rid of the Constructor with Field Injection

Field injection is the solution for getting rid of constructors altogether.  Field Injection is the ability to inject the implementation of a dependent class directly to a field reference without actually calling Create manually.  The Delphi Spring Framework provides two ways for doing field injection.

Consider the following class declaration:

type
  TOrderProcessor = class(TInterfacedObject, IOrderProcessor)
  private
    [Injection]
    FOrderValidator: IOrderValidator;
    FOrderEntry: IOrderEntry;
  public
    function ProcessOrder(aOrder: TOrder): Boolean;
  end;

Note first that the class has no constructor.  It still contains references to the two internal interfaces that we saw above, but there is no formal constructor.  The second thing to note, of course, is the [Injection] attribute.  This is the key here.  This attribute tells the Spring Framework – “When you first encounter this identifier, go to the Container and grab the implementation for that interface and assign it. “ Basically, it tells Spring to do everything for you, including creating an instance of the implementing class for the interface. 

Thus, for our TOrderProcessor class, we can have no constructor, but freely use the interfaces declared as private fields:

function TOrderProcessor.ProcessOrder(aOrder: TOrder): Boolean;
var
  OrderIsValid: Boolean;
begin
  Result := False;
  OrderIsValid := FOrderValidator.ValidateOrder(aOrder);
  if OrderIsValid then
  begin
    Result := FOrderEntry.EnterOrderIntoDatabase(aOrder);
  end;

  {$IFDEF CONSOLEAPP}
    WriteLn('Order has been processed....');
  {$ENDIF}
end;

The above code will run just fine, despite the fact that at no time does the code itself ever explicitly create a class for the interfaces. 

But wait, you say – what about FOrderEntry?  It doesn’t have the [Injection] attribute.  You are right.  Instead, we do field injection directly as part of the interface/class registration process.  In the initialization section of the declaring unit, the registration looks like this:

initialization
  GlobalContainer.RegisterComponent<TOrderProcessor>.Implements<IOrderProcessor>.InjectField('FOrderEntry');

 

At the very end, you’ll notice that there is a call to InjectField(‘FOrderEntry"’); which tells Spring the same thing that the [Injection] attribute does.  In fact, the [Injection] attribute actually invokes the very same code to ensure that the reference is correctly assigned.  (You can see the whole unit here in BitBucket).

So there, we did it:  We created a useful class that uses two other classes and we didn’t create anything and we didn’t couple anything to anybody.  Pretty nice, huh?

Conclusion

Okay, so now we are able to write classes that is so decoupled from each other that they don’t even have to create instances for use!  We used Field Injection to automatically get references to objects that implement our interfaces without doing anything at all.  These classes are so decoupled that you don’t even have to include the units that implement the classes in any uses clause other than your application’s *.DPR file.  And as we said at the start, “Decoupling is good and coupling is bad”.  (If I didn’t say that, I should have, right?) 

Flotsam and Jetsam #44

By Nick at September 21, 2011 23:58
Filed Under: Flotsam and Jetsam, Delphi
  • If you haven’t figured it out, I’m all cuckoo for the Delphi Spring Framework.  Some folks were worried that the project was stagnating, though it hadn’t been that long since it had been changed.  Well, at least until yesterday, when a big set of changes were made with the idea of heading towards a 1.0 release.  There were quite a few fundamental changes, with some things formerly marked experimental moving to the “ready to go” stage, and a few new things (like the Logging units) being added and marked experimental.  And if you look really closely, you’ll even notice some small changes by yours truly.  There are some really cool things going on in this framework, and I highly recommend giving it a look.  I’ll be writing more articles here on the blog, and trying to update the documentation, FAQs, and other stuff as part of the project.  I also have some demo applications that I’ll be commenting and adding to the project.
  • I still see people trying to obfuscate their email address online. You know, doing things like “Email me at nick at nickhodges dot com” or something like that.  I personally have given up doing anything like this, figuring that spammers will eventually get any email address I have, and that it’s pointless to try to avoid it.  Spam Filters have gotten pretty good, and I only see a few spam messages a day.  And I’m not one of those guys that freaks out at the site of a single unsolicited email, preferring instead to take the 0.0023 seconds it takes to click the delete button.
  • Jacob Thurman is at it again – this time updating his very cool and powerful IDE enhancement Castalia to work with Delphi XE2.  I’ve always admired what Jacob does, and I think you should, too.  I mean, how can you not love a product that has a bullet point that says “Enhanced: Rewritten “Eliminate With” refactoring is more reliable”.  I mean, “Eliminate With”?  Is there a cooler refactoring anywhere?
  • From the “You learn something new every day” category:  I didn’t realize that Delphi doesn’t generate RTTI for enumerations that have assigned values (i.e.  type TMyEnum = (Five= 5, Six = 6);
  • One of the new features in Delphi XE2 is the ability to style your VCL apps.  The product ships with a bunch of styles, and provides a style designer that lets you build your own styles.  Well, it didn’t take long for Rodrigo to get to work and build a bunch of styles that you can use.  You can download his styles, and then put the *.VSF files in your style directory.  On my machine (I install to the default location) that directory is:  C:\Users\Public\Documents\RAD Studio\9.0\Styles\.  He’s put together a really nice looking set of styles. Thanks, Rodrigo!

My Book

A Pithy Quote for You

"Luck is what happens when preparation meets opportunity."    –  Seneca

Amazon Gift Cards

General Disclaimer

The views I express here are entirely my own and not necessarily those of any other rational person or organization.  However, I strongly recommend that you agree with pretty much everything I say because, well, I'm right.  Most of the time. Except when I'm not, in which case, you shouldn't agree with me.