Sunday, September 25, 2011

AOP and duck typing in Delphi

AOP - something that fascinated me from the very first moment when my coworker told me about PostSharp. Unfortunately something that was almost impossible in Delphi without the proper knowledge of assembler and all the internal low level stuff. However even with Delphi 7 it was possible to a certain degree to intercept virtual methods using MeAOP.

With the recent additions (namely enhanced RTTI) it became very easy to introduce this feature in a more safe way. However this is nothing compared to a framework like PostSharp which is able to enhance almost everything using IL weaving. Currently you can intercept any virtual method that has RTTI (by default any public/published method). It is very similar to what DynamicProxy does. Delphi XE introduced the TVirtualMethodInterceptor that made it possible to intercept the virtual method calls of an existing object. This is done by creating a new VMT at runtime and attaching it to the object. I went a step further and made it possible to patch any existing class VMT so that any object of this class (and every derived class if you wish) can be intercepted. You can add any aspect to any method you like (if it is virtual and has RTTI). There is currently one built-in aspect for logging which logs entering and leaving the method, all parameters and the result if there is one. You can find a simple demonstration on how to instrument two virtual methods to show logging in the SVN repository.

Did you ever face the problem of having a dependency in your code that you could not remove so simply? Like having that class in your code that is passed around but not being part of your source code so you cannot mock it out? Well you could inherit that class and implement some interface so you just have the dependency on that interface. Yes if that class is not sealed (did you know you can use that keyword in Delphi?). To be honest I haven't seen anyone using this yet (could be because I mostly work with sourcecode written in Delphi 7). But let's say you have a class that is sealed and you want to remove the dependency. You could write an abstract wrapper class and then inherit from it to remove the dependency from your code. Sounds like a lot of work, right?  How about duck typing?





When you look at what duck typing means this is very similar to as if the class implements a specific interface. "Walks like a duck and swims like a duck and quacks like a duck" basically means it got these 3 methods. Like implementing IDuck with these 3 methods. But duck typing does not require the class to implement this interface. Prism got duck typing just recently and DSharp now got it too! (only for XE2 yet, sorry) Of course no compile time support but something similar to what the RemObject guys call soft interfaces and dynamic duck typing mode.

Here is the program from the wikipedia page in Delphi!

program DuckTypingSample;

{$APPTYPE CONSOLE}

uses
  DSharp.Core.DuckTyping;

type
  IDuck = interface(IInvokable)
    procedure Quack;
    procedure Feathers;
  end;

  TDuck = class(TInterfacedObject, IDuck)
  public
    procedure Quack;
    procedure Feathers;
  end;

  TPerson = class
  public
    procedure Quack;
    procedure Feathers;
    procedure Name;
  end;

{ TDuck }

procedure TDuck.Feathers;
begin
  Writeln('The duck has white and gray feathers.');
end;

procedure TDuck.Quack;
begin
  Writeln('Quaaaaaack!');
end;

{ TPerson }

procedure TPerson.Feathers;
begin
  Writeln('The person takes a feather from the ground and shows it.');
end;

procedure TPerson.Name;
begin
  Writeln('John Smith');
end;

procedure TPerson.Quack;
begin
  Writeln('The person imitates a duck.');
end;

procedure InTheForest(duck: IDuck);
begin
  duck.quack();
  duck.feathers();
end;

var
  donald: IDuck;
  john: TPerson;
begin
  donald := TDuck.Create;
  john := TPerson.Create;
  InTheForest(donald);
  InTheForest(Duck<IDuck>(john));
  john.Free;
  Readln;
end.

Notice how this is different from dynamic typing you could do with invokable variants. Like the variants approach the evaluation is done at runtime. But in this case you have more type safety. Instead of just passing a variant to the InTheForest procedure and not having any type safety (you could also write duck.Bark() and compiler would not complain) you only can call methods of the IDuck interface. If the wrapped object does not have the required method (also matching parameters) it throws the not implemented exception.

What is it good for? This can open up certain parts of your application to unit testing and mocking that you could not do before because you had lots of static dependencies that could not be mocked. And of course to show that Delphi is catching up. ;)

Saturday, September 24, 2011

DSharp Bindings vs LiveBindings

I think it's finally time to compare these two things and see which one may fit you better. This is my point of view that may not be completely objective.

When I noticed that there was actually no language support for LiveBindings I was very disappointed. I think without language support you cannot create anything that works much different from how DSharp Bindings work. And actually LiveBindings don't. I could not just change the VCL source code so I had so come up with some "hack" (using the interceptor pattern by including the VCLControls unit that subclasses the supported VCL controls). Of course the guys at Embarcadero had the power to change the VCL classes and that is why they implemented the observer pattern into TComponent I guess. Did you notice that is not that easy to connect simple TObject descendants with LiveBindings? Another thing is that you cannot just connect your Edit to some other component, set up the binding and it works. You still have to write code into your OnChange event because the observer only is activated when you use TBindLink. And this will usually set your edit to read only unless the SourceComponent implements some specific interface. I am very sure the whole BindLink part of the LiveBindings was only for enabling data sensitive controls for FireMonkey (something I have not looked much at yet).

In my opinion for simple bindings like displaying some address or customer Data the point goes to DSharp. It "just works" instead of having to write extra code which should not be required because that's the purpose of bindings.

So what about more complex data like displaying a list of objects in a grid? DSharp does not support any grids yet but it got support for listview, treeview and the virtual treeview. Supporting the stringgrid is on the list and will definitely come. How does it work? Well you just connect your list to the view property of the supported control and you specify a data template that needs to be written in delphi. In fact it turns out to be a bit more complex sometimes. When using the virtual treeview and the treeview presenter you want to specify the columns and then you can bind these columns to the properties of your objects in the list. Have you tried yet to bind a list to some listview or stringgrid using LiveBindings? I have and I failed. To be honest I gave up very quick because this was just so cumbersome and required several string based expressions. Did I mention that the documentation on the new features in XE2 especially LiveBindings sucks? Well yeah my documentation does as well, but I don't have a documentation team working for me, right?

Again DSharp Bindings are focused on doing simple things very easily without locking you out when you want to do more complex things. LiveBindings are very unintuitive to use. I think this point also goes to DSharp.

What about connecting your dataset to some controls? This is something I haven't done since ages (except when working with a grid) but this is where LiveBindings got their power - as I said earlier I think their major task is doing exactly this. Unfortunately the designtime support for this is only enabled in FireMonkey but in VCL you have the DB controls anyway. DSharp just does not support this. I have thought about implementing it but I don't see the point. If you want to use datasets just use db controls which have been working for ages. In FireMonkey you just connect your edit to a field with a few clicks.

Point for LiveBindings.

As you may know there is some expression engine sitting below the LiveBindings that can do some nice things like calculating, concatenate strings and much more. There are built-in functions that can be used (like UpperCase, Round or FormatDateTime). I am happy to tell you that DSharp got an integration with DWS just yesterday. So you can basically use everything that DWS can do in your bindings. From making your text capital letters to doing complex calculations or even evaluating business rules if you like. Since DWS is a real scripting engine you have way more power than the LiveBindings expression engine..

I am very sure with this latest addition this point goes to DSharp.

If you don't trust open source because it may not be continued in the future or does not give you the feeling of safety you may use LiveBindings. Also LiveBindings are ahead regarding designtime support - even if it is kind of cumbersome setting them up sometimes.

For being the "official solution" LiveBindings deserve this point.

So the final score is 3 to 2 for DSharp in my opinion. Again I have not been digging through tons of samples and documentation and since Embarcadero always just shows tons of fancy stuff in FireMonkey, other platforms and so on the documentation on this feature is not very present. I like simple solutions to simple problems. I totally hate full blown over-engineered solutions that are a pain to use in your daily business. And I have the feeling LiveBindings are over-engineered and not well designed. Otherwise they would be easy to use like throwing an edit and a button and the form and make them work, right?

If you like using data bindings in any Delphi 2010 or newer you should definitely take a look at DSharp. Also there is much more in it than just data bindings.

Sunday, September 18, 2011

Pimp your unit tests using mock objects

Have you ever faced the problem of having dependencies in your unit tests that made it hard to actually write a unit test instead of writing an integration test? Often you have that problem with bad designed code that does not follow certain principles. But also with well designed code you might end up having your one class you want to test which depends on 3 other classes which might as well depend on other classes. At this point you actually benefit from well designed code. You can use so called mock objects in your unit tests.

Wikipedia describes them as "simulated objects that mimic the behavior of real objects in controlled ways". Other programming languages like Java and C# are using them for years and in fact also for Delphi there are some mocking frameworks. The problem with the existing frameworks in Delphi are that they either rely on generated code (like Delphi Mock Wizard) or strings for defining the expected method calls (like PascalMock).

In the past I already showed you some cool things I found in Emballo (which was developed in Delphi 2009 before the new enhanced RTTI was introduced). The author used a technique similar to what was introduced in Delphi XE in form of TVirtualMethodInterceptor but in a more limited way due to the lack of TValue and generics. With his permission I used this concept to create a more advanced version of mocking for Delphi. It was also inspired by NMock and in the following I will use the example from their tutorial to show you what you can do with DSharp Mock.

First let's see what it can do and what not. As it depends on TVirtualMethodInterceptor you can only mock virtual methods that can be seen by RTTI (public and published by default). And you can only use it in Delphi XE and higher. If you are using XE2 you can also mock Interfaces that contain RTTI (inherit them from IInvokable or add the $M+ directive) and have a guid.

In the following example I will use classes and virtual methods (the example from NMock uses interfaces but I also wanted to share this with those of you using XE).

We have a very simple scenario: a class (TAccountService) that can transfer money from one account to another using different currencies. The conversion rate is provided by another class (TCurrencyService). Both classes have abstract base classes (TAccountServiceBase and TCurrencyServiceBase). We now want to unit test our TAccountService without using the concrete TCurrencyService class (which does not even is part of this unit test). Let's take a look at the code:

interface

type
  TAccountService = class(TAccountServiceBase)
  private
    FCurrencyService: TCurrencyServiceBase;
  public
    constructor Create(ACurrencyService: TCurrencyServiceBase);

    procedure TransferFunds(
      ASource, ATarget: TAccount; AAmount: Currency); override;
  end;

implementation

constructor TAccountService.Create(ACurrencyService: TCurrencyServiceBase);
begin
  FCurrencyService := ACurrencyService;
end;

procedure TAccountService.TransferFunds(
  ASource, ATarget: TAccount; AAmount: Currency);
begin
  ASource.Withdraw(AAmount);
  ATarget.Deposit(AAmount);
end;

Our currency service base class looks as simple as this:
type
  TCurrencyServiceBase = class
  public
    function GetConversionRate(AFromCurrency, 
      AToCurrency: string): Double; virtual; abstract;
  end;

Now let's create our test method to check if the TransferFunds method works correct.

procedure TCurrencyServiceTest.TransferFunds_UsesCurrencyService;
var
  LAmericanAccount: TAccount;
  LGermanAccount: TAccount;
begin
  LAmericanAccount := TAccount.Create('12345', 'USD');
  LGermanAccount := TAccount.Create('54321', 'EUR');
  LGermanAccount.Deposit(100);

  FMockCurrencyService.WillReturn<Double>(1.38)
    .Once.WhenCalling.GetConversionRate('EUR', 'USD');
  try
    FAccountService.TransferFunds(LGermanAccount, LAmericanAccount, 100);

    Verify.That(LGermanAccount.Balance, ShouldBe.EqualTo<Double>(0));
    Verify.That(LAmericanAccount.Balance, ShouldBe.EqualTo<Double>(138));

    FMockCurrencyService.Verify();
  finally
    LAmericanAccount.Free();
    LGermanAccount.Free();
  end;
end;

First we are setting up 2 dummy accounts and deposit 100 euro on the german account.

After that it gets interesting. We define that the currency service will return 1.38 once when the method GetConversionRate gets called with the exact arguments.

After that we are calling the method we want to test. We are transferring 100 euro from the german account to the american account.

Then we want to check if this transfer went correct. So we are checking if the balance on the german account is 0 and the american account has a balance of 138 us dollars. You could use the regular Check methods of DUnit just like I did at first. Unfortunatly I ran into the problem with comparing floating numbers and the test failed for values that should be equal. This is because the DUnit CheckEquals method doesnt have overloads for all the floating types and it does not take the imprecision into account like for example the Math.SameValue functions. Also they are not easily to read in my opinion.

There is some extension for DUnit out there called DUnitLite that does something similar. Anyway also NMock has this Verify class that makes use of fluent interface syntax to make your checks more readable - almost like a real sentence. Internally it uses the DUnit exceptions so you will see some nice message when your check fails.

You probably already noticed that we were missing the call to the currency service so the transfer went wrong and we only have 100 us dollars on that account. Our unit test is telling us: "Expected: "? = 138" Actual: 100" That is what happens if you convert prices one to one. Good thing we would never do that and we fix that in our method.

procedure TAccountService.TransferFunds(
  ASource, ATarget: TAccount; AAmount: Currency);
var
  LConversionRate: Double;
  LConvertedAmount: Currency;
begin
  ASource.Withdraw(AAmount);
  LConversionRate := FCurrencyService.GetConversionRate(
    ASource.Currency, ATarget.Currency);
  LConvertedAmount := AAmount * LConversionRate;
  ATarget.Deposit(LConvertedAmount);
end;

Now our test runs successful. But there was one more line in our unit test we did not talk about yet. The Verify method checks if all expected method calls were made and none was missing. Any unexpected method call would have caused a failure immediately. For example if we swapped the currencies by mistake.

For the full syntax provided and how to set up mocks look at the sample in the repository. I am working on writing documentation for DSharp (thanks Paul for a Documentation Insight license) so it will be easier for you to understand and use in the future.

I think this possibility of writing your unit tests in a more declarative way without having to write a whole bunch of code just to mock dependencies makes writing tests more easy and less time consuming. Also reading them is much easier because you can just see what expectations are made on the dependencies and you can find out much easier what caused a test to fail.

As usual you find the source in the SVN repository.

Friday, September 2, 2011

Delphi XE2 - heating up the hype: playing the matchmaker for VCL and FMX

To be honest, FireMonkey did not interest me much because of the fact that it is not compatible with any VCL application - says the documentation - actually that's not the truth!

To keep the long story short: You can have both in one! (Disclaimer: I did only a few tests and it worked all fine - actually I have no clue if somewhere it's incompatible but I leave that as an exercise to you).

Just create a new FireMonkey form (2D or 3D, doesn't matter) save it and then add it to your VCL application (just accept the warning). You can create your FMX form instance somewhere and just show it - no problem. But what if you want to create some nice control with animations or something and embed it into your existing VCL form? Well, put a TPanel on your VCL form and include the brandnew unit DSharp.Windows.FMXAdapter.pas after the Vcl.ExtCtrls. Then just create your FMX form somewhere and assign it to the new Form property of your Panel - and boom, there you go.

As I said, I just came up with this and it's mostly untested - but that's the case for FireMonkey anyway, isn't it? So I thought this may be very interesting for a few people - especially those that used VGScene before. So have fun creating your shiny and new FMX forms and use them in your existing VCL apps. ;)

Thursday, September 1, 2011

Delphi XE2 - features aside from the hype: TVirtualInterface

While prolly almost everyone was creating fancy FireMonkey or VCL applications for Windows (32-bit and 64-bit), OSX and/or iOS with Delphi XE2 today I took a look at one of my favorite units in the RTL - System.Rtti.pas.

When you look at the RTL Changes for XE2 you will see a new addition to the RTTI - TVirtualInterface. Along with this comes another improvement: RTTI can finally tell the implemented interfaces of a class (and its ancestors). But back to the TVirtualInterface!

Documentation says: "Provides functionality for remote procedure call marshaling. TVirtualInterface creates an implementation of an interface at run time." Wow, this sounds interesting. Further reading states that it's main purpose is SOAP messaging. A client can consume a service with several methods just by calling them through an interface which then "just calls" the remote methods of the service. I think this is awesome because it leads to clear defined interfaces (literally) when working with remote services or other things that just hide behind the interface and which are not necessary to be known. Other things I say...

Some while ago when I came across the Emballo Framework I was impressed by the DLLWrapper which basically imports exported functions of a DLL and provides them through an interface. Of course there have to be some rules like the calling conventions and the parameters have to match. But you can do define an interface like this:

type
  IMyLibrary = interface
    ['{8B47F556-673B-44D6-8F90-09985B3C53E0}']
    function SayHello: string
  end;

And then simply import a DLL which exports this function and just call it. It was a bit rough and actually only supported a few types and not all calling conventions. So I am very happy to have a tool out of the box that makes it possible to write something like this:

if Supports('MyLibrary.dll', IMyLibrary, LMyLibraryIntf) then
  ShowMessage(LMyLibraryIntf.SayHello());

Those of you that worked with .Net in RAD Studio 2007 may know this - it was called Virtual Library Interfaces. I have not tried yet, but I am sure if you have the correct signature in your interfaces methods you can call almost every DLL. Actually the Supports functions does not exist in Delphi but you can find it in the brand new unit DSharp.Core.Plugins.

I uploaded a simple sample how to use this (including the new unit which can also be downloaded from the svn repository).

I also added the DSharp packages for XE2 today (only 32-bit for now, 64-bit compatibility will follow soon). I know there is some issue with the asm code in the DSharp.Core.Events (that has to go for 64-bit anyway) which break bindings for now - but I am working on it. Also more about LiveBindings vs DSharp soon.