Amazon.com Widgets January 2013

Delphi and the Observer Pattern

By Nick at January 27, 2013 11:46
Filed Under: Delphi, Patterns, Software Development

I’m currently reading Head First Design Patterns, and am finding it very useful and educational.  One problem, though – it’s all in Java.  So I thought that as part of the exercises, I’d translate the code to Delphi.  And also as part of my learning process, I thought it would be a good idea to post an article about each of the patterns.  I also encourage you to buy the book and read it for yourself.

The first real pattern that the book shows is the Observer Pattern.  You should use the observer pattern when you have one object that notifies other objects when events occur.    Or more succinctly, use it when you have an object that needs to notify other objects about stuff that happens. 

HFDP uses the example of a simple weather station that gathers data about the weather.  Each time the weather station takes readings, it needs to update the views of that weather. The weather station reports on Temperature, Humidity, and Pressure.  There are three views that the application provides – current conditions, statistics about the weather, a simple forecast.

The idea here is that the weather station is the subject – it is the object being observed and doing the notifying.  The different displays for the information are the observers – they watch what happens on the weather station and update themselves based on the notifications that they receive from the weather station.  Another way to look at it is that the weather station is a publisher of information, and the displays are subscribers.

The formal definition given for the Observer Pattern goes like this: The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically. 

But when it comes time to implement this, the temptation is to simply embed the displays inside of a method of the weather station.  You might create classes for each view, instantiate them in the weather stations constructor, and then simply update the views in a method called MeasurementsChanged.

But of course if you do this, you are breaking some of the base design rules.  First, you’d be coding against an implementation instead of against an interface.  Second, you’ve made it really hard to add a new data display should that become necessary.  Displays are hard-coded into the weather station and can’t be added or removed at runtime.  If we do want to add more displays, we’d need to modify the weather station itself.  Or, put more succinctly, the weather station and its displays are tightly coupled to each other.  And if you know one thing about me, I abhor tight coupling.  And you should too.

In any event, there is a better way – the Observer Pattern.  As noted above, observer pattern consists of a Subject that is monitored by Observers.   We’ll implement a very simple version of the observer pattern. The first thing we will do of course, is declare two interfaces:

type
  IObserver = interface
  ['{69B40B25-B2C8-4F11-B442-39B7DC26FE80}']
    procedure Update(aTemperature: integer; aHumidity: integer; aPressure: Double);
  end;

  ISubject = interface
  ['{A9240295-B0C2-441D-BD43-932AF735832A}']
    procedure RegisterObserver(aObserver: IObserver);
    procedure RemoveObserver(aObserver: IObserver);
    procedure NotifyObservers;
  end;

The first interface is IObserver, which the observing classes will implement.  In it they’ll be updated with all the weather information that the weather station has for us.  The second is ISubject, which will be implemented by the weather station.  It takes three methods, two for handling the connecting and disconnecting of IObservers, and the third for doing the actual notification to the observers. 

The first implementation we’ll look at is the Weather Station.  Here is its implementation declaration.

type
  TWeatherData = class(TInterfacedObject, ISubject)
  private
    FTemperature: integer;
    FHumidity: integer;
    FPressure: double;
    FObserverList: TList<IObserver>;
    function GetTemperature: integer;
    function GetHumidity: integer;
    function GetPressure: double;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SetWeatherInformation(aTemperature: integer; aHumidity: integer; aPressure: double);
    procedure RegisterObserver(aObserver: IObserver);
    procedure RemoveObserver(aObserver: IObserver);
    procedure NotifyObservers;
    procedure MeasurementsChanged;
    property Temperature: integer read GetTemperature;
    property Humidity: integer read GetHumidity;
    property Pressure: double read GetPressure;
  end;

The plumbing for managing the weather implementation is all what you’d expect.  The interesting part, of course, is the implementation of ISubject.  Internally, it uses a TList<IObserver> to manage all the observers that get registered with it.  The RegisterObserver and RemoveObserver methods simply insert and remove, respectively, instances of classes that implement the IObserver interface.

The real action occurs in the NotifyObservers method.  We’ll get to that in a second.  First, though, let’s take a look at the observers.  Since all the displays are very similar, this is a good time to use good old-fashioned inheritance to declare a base class that implements the needed functionality, and then have descendent classes that do the work of providing the specified displays.  Here, then, is the interface for TWeatherDataDisplay:

TWeatherDataDisplay = class(TInterfacedObject, IObserver, IDisplay)
  private
    FSubject: TWeatherData;
    FTemperature: integer;
    FHumidity: integer;
    FPressure: Double;
  public
    constructor Create(aWeatherData: TWeatherData);
    destructor Destroy; override;
    procedure Update(aTemperature: integer; aHumidity: integer; aPressure: Double); virtual;
    procedure Display; virtual; abstract;
  end;

TWeatherDataDisplay has fields to keep track of the current weather information.  It’s descendants can do with it as they please.  It also implements the IDisplay interface so that it can report out what it has to say.  The Update method will allow the Subject – in this case the weather station – to update the displays.  Update is a virtual method, by the way, so that descendants can do different things with the incoming information. 

Okay, so let’s look under the hood.  The weather station can accept and remove IObserver implementers at runtime.   implements the NotifyObservers method as part of the ISubject interface.  It gets called whenever the weather information changes.  It is implemented as follows:

procedure TWeatherData.NotifyObservers;
var
  Observer: IObserver;
begin
  for Observer in FObserverList do
  begin
    Observer.Update(Temperature, Humidity, Pressure);
  end;
end;

This is pretty simple – it merely enumerates over each item in the observer list and calls the Update method, passing along the new weather data.  The base class stores the information, and its descendants process it.

The real “work” gets done when the weather station updates the temperature data and calls NotifyObservers:

procedure TWeatherData.SetWeatherInformation(aTemperature, aHumidity: integer; aPressure: double);
begin
  FTemperature := aTemperature;
  FHumidity := aHumidity;
  FPressure := aPressure;
  MeasurementsChanged;
end;

The entire implementation of our little weather station can be found as part of my demo code on BitBucket.org.

So all of this comes together in a method to create a weather station and add observers:

procedure DoWeatherStation;
var
  WeatherStation: TWeatherStation;
  CurrentDisplay: IDisplay;
  ForecastDisplay: IDisplay;
  StatsDisplay: IDisplay;
begin
  WeatherStation := TWeatherStation.Create;
  try
    CurrentDisplay := TCurrentConditionsDisplay.Create(WeatherData);
    ForecastDisplay := TForecastDisplay.Create(WeatherData);
    StatsDisplay := TStatisticsDisplay.Create(WeatherData);;
    WeatherStation.SetWeatherInformation(70, 55, 28.90);
    WeatherStation.SetWeatherInformation(68, 59, 28.96);
    WeatherStation.SetWeatherInformation(35, 66, 27.40);
    WeatherStation.SetWeatherInformation(55, 55, 27.40);

  finally
    WeatherStation.Free;
  end;
end;

Here are some interesting things to note:

  • This code doesn’t write anything to the console.  All of that is done by the display objects that get registered as observers.  Each observer is registered, and the code pretty much forgets about them.  To the weather station, they are merely IObserver interfaces, and the only thing you can do to an IObserver is call it’s Update method.  From the Weather Station’s perspective, there’s nothing else to it.
  • Four calls to SetWeatherInformation result in for reports from all of the updates to the temperature information.
  • Once you have a reference to a TWeatherStation, you can add or remove displays at runtime.
  • TWeatherStation doesn’t know anything about Weather displays – it only knows about IObservers.  This means that you could have observers that do other things besides being Weather Displays.  You could simply store the weather data, or anything else at all.  For instance, you could create a TWriteWeatherInfoToDatabase class that implements the IObserver interface.  The Weather Station itself neither knows nor cares.  IObservers are under no obligation to do anything specific with the data passed to them. 
  • We can change the observers anytime we want without altering the Subject.  We can add new observers, too.  Basically, observers and subjects are very loosely coupled, and either can be changed, altered, updated, and added to without having to worry about changing the other. 

So that should be a quick rundown on how the observer pattern works.  The obvious weakness here is that our IObserver interface is very specific to weather data.  You can create your own interface for your specific implementation.  The pattern remains the same no matter how the IObserver interface is designed.  This is obviously a good place for generics to enter the picture, and in fact, the Delphi Spring framework implements a generic IObservable<T> interface and implementing class.

So in summation, the Observer pattern ensures that publishing classes (subjects) can communicate updates to their subscribing (observer) classes with very loose and flexible coupling.  Observers can be updated and removed at runtime.  Adding observers requires no change to subjects.  Subjects don’t know much at all about what the observers are up to.  It’s all very easy and elegant and loosely coupled – just like you want it.

Next up – the Decorator Pattern.

Flotsam and Jetsam #76

By Nick at January 26, 2013 04:11
Filed Under: Delphi, Flotsam and Jetsam
  • There are a lot of cool things that an IDE could do, but it’s getting to the point where my one top feature for the IDE is the automatic addition of interface methods.  If I declare a class that implements a given interface, the IDE should automatically fill those in for me.  That would be really sweet.  This feature is in third place in the IDE section of Delphi’s User Voice page. Feel free to vote for it.
  • The fine folks at TMS Software are organizing a Delphi/TMS day in the Benelux region – if you are around you should go.  They  have early bird registration until 01 March 2013.
  • Embarcadero has announced the coming of Delphi for iOS.  I’m not an iOS guy – I’m waiting for the Android stuff.  I don’t have an Apple device at all, and you need one to develop on.  (There’s no iOS emulator or simulator for Windows – everything has to run on Apple hardware/software…) so it’s not of any use to me at the present.  However, I’ll be keeping a close eye on this, as I’ll be developing for Android as soon as I can with Delphi, and I suspect I’ll eventually be wanting the results of that to run on iOS as well.  After all, that is one of the promises of FireMonkey – to have a single codebase that runs on Windows, iOS, and Android.  In any event, no one can say that Delphi isn’t alive and kicking.  The new offering includes a Delphi compiler for ARM chips, which is pretty exciting if you’ve been wanting Delphi to branch out.  And the best part is you can get early access to the beta if you buy XE3.
  • Looks like David I has something up his sleeve this year on Delphi’s birthday
  • Delphi Developer Days is back this year – with two dates in Europe and just one in the US (Chicago).  Cary has all the details.  I’ve been to a couple of the events, and they are really fun and well worth the time.  If you can make it, I strongly recommend the event.  Dr. Bob is certainly a more than able replacement for Marco.  With no Delphi Live in the future, this is really the only US conference where Delphi folks can gather.  I’d like to see them add an East Coast date in the US.  Otherwise, I’ll try to get to the Chicago event. 

Flotsam and Jetsam #75

By Nick at January 20, 2013 03:44
Filed Under: Delphi, Flotsam and Jetsam
  • Now here’s a blog after my own heart:  LooseCouplings.com  Sadly, it hasn’t been updated in a while, and there are only a few articles, but what is there is really good.  There are four or five articles about Dependency Injection (particularly about how it doesn’t necessarily mean using a DI Container…..) and we’d all do well to read and heed. Thanks to Stefan Glienke for pointing me to it.
  • RAD Studio won the “Top Innovator: Developer Tools” at the Developer Week Conference.  Nice thing to see.
  • I wanted to strengthen my SQL skills, so I decided to give Head First SQL a try.  It was my first foray into the world of the Head First Series, and I was pleasantly surprised. I wasn’t quite sure what to expect, but what I got was a great review/tutorial on SQL.  The examples were simple but to the point, the style a touch irreverent but enjoyable, and I actually did, and learned from, the exercises.  Now I’m working on Head First Design Patterns which so far is the same: excellent, interesting, and attention-holding. I do believe that I'll seek out Head First titles in the future if I want to learn something new.
  • I’d like to put in another plug for the Google Plus Delphi Developers Community.  We’ve been having a lot of fun over there – or at least I have, maybe the rest of the folks are sick of me.  Winking smile  In any event, please stop by and participate. 
  • Shameless Plug of the WeekSign up for Sprint cell phone service.

Flotsam and Jetsam #74

By Nick at January 13, 2013 12:56
Filed Under: Delphi, Flotsam and Jetsam
  • A while back I wrote a “How Not To Code” about not using Booleans as method parameters.  This line of real-world code that I ran across today -- myMonster.Run(cSourceStateLicenseWebNew, '1', '', False, False); -- is a perfect example of why this shouldn’t be done.  Who the heck knows what those last two parameters mean?
  • Does anyone know if that is real Chinese they speak in Firefly?
  • I don’t know if this is good or bad, but apparently I’ve visited StackOverflow on 1001 distinct days.  Yikes. (Maybe more by the time you read this….)
  • This is a really nice article on attributes by Francois Piette. I’m bummed because he used the example that I was going to use in my book.  Anyone got any better ideas?
  • Okay, I did a little more research on Arduino vs. Raspberry Pi, and I think I’m going to start with the Arduino. It seems more “science project-y” whereas the Raspberry Pi seems more like a complete computer solution.  Both sound great, but I’m more interested in the “controlling something” aspect rather than the “use all that small but powerful computing power”.  I think the Arduino would provide more stuff for me to do with my kids in terms of “making it all come alive”.  That’s kind of what I’m interested in, really – the “Mr. Science” kind of stuff.  Thanks to you all for the feedback.
  • I never talk much about Lazarus/FreePascal because I don’t use it and I’m not much interested in it, but it is starting to move more to the center of my radar as apparently you can use it to program a Raspberry Pi.  In fact, our friend Jeff Duntemann has set up a Raspberry Pi as a “regular” computer, and is using Lazarus to write code for it.  Not only that, he’s working on rewriting his classic “Borland Pascal from Square One” for Free Pascal, the current version of which you can download as a PDF.  He also reports that he’s doing a book on Lazarus.  It’s always good to see activity in the world of Pascal and Delphi Programming. Now if we could just get Delphi for Arduino, I’d be in heaven.  Winking smile   
  • I for one welcome our new drone overlords.

Enumerating and the for…in Loop

By Nick at January 12, 2013 06:05
Filed Under: Delphi, Software Development

One of those fun little issues in our business is trying to figure out the difference between iterating and enumerating.  This StackOverflow answer does a pretty good job of explaining it.  Iterating is doing something – usually a series of steps – over and over again.  Enumerating is going over each item in a given collection.  A subtle difference, sure.  One usually iterates when enumerating. 

Okay, so enumerating is going over each item in a collection.  IEnumerable can enumerate over the items in a collection as we saw in my last article.  But you can enumerate over other things as well.  For instance, in Delphi, you can use the for…in statement to enumerate over the characters in a string. 

But this makes me wonder:  how does something become, well, enumeratable?  How do you make something so that you can use with the for…in statement? 

Well, it’s pretty easy.  The rules for Delphi are simple:

  • To create a class or record to enumerate, it must provide a method called GetEnumerator() which in turn needs to be a function that returns a class, an interface, or a record that is an enumerator.
  • To be returned as an enumerator, that class, record, or implemented interface needs to have the following:
    • A method called MoveNext that returns a Boolean indicating whether the end as been reached or not
    • A read-only property called Current that indicates the item that is currently being “looked at” as the enumeration occurs. 

So, at this point, a simple demo would be helpful, eh?

You can already enumerate the characters in a string, but it’s a simple example, and so the following example implements this easy to understand enumeration on a string:

TForInDemoClassEnumerator = class
  private
    FString: string;
    FIndex: integer;
  protected
    function GetCurrent: Char; virtual;
  public
    constructor Create(aString: string);
    function MoveNext: Boolean;
    property Current: Char read GetCurrent;
  end;

TForInDemo = class
  private
    FTheString: string;
    procedure SetTheString(const Value: string);
  public
    constructor Create(aString: string);
    function GetEnumerator: TForInDemoClassEnumerator;
    property TheString: string read FTheString write SetTheString;
  end;

 

This code declares two classes.  The first class is the enumerator – the class that does the work of  moving over each item, and which will be returned by the call to GetEnumerator.  The second is the class that will be enumerated.  Notice, too, that TForInDemoClassEnumerator has the read-only property Current with the reader GetCurrent and MoveNext methods.  The TForInDemo class has a call to GetEnumerator that returns an instance of TForInDemoClassEnumerator

First let’s look at TForInDemoClassEnumerator.  You create it by passing the constructor the item to be enumerated – in this case a string.  Hence, the constructor:

constructor Create(aString: string);

Here is the implementation of the MoveNext method:

function TForInDemoClassEnumerator.MoveNext: Boolean;
begin
  Result := FIndex < FString.Length;
  if Result then
  begin
    Inc(FIndex);
  end;
end;

This code does two things.  First, it sets the result. The function returns True if the enumerator is able to move to the next item, and False if it has reached the end of the items to be enumerated.  In this case, it merely checks to see the index is before the length of the string.   If the end has not yet been reached, it just increases the FIndex field.  So it’s job here is merely to move the index along, and report if the end has been reached.

The actual item itself is returned by the GetCurrent method, which is self-explanatory:

function TForInDemoClassEnumerator.GetCurrent: Char;
begin
  Result := FString[FIndex];
end;

And that is it for the enumerator.  It’s pretty simple.  But we’ll soon see that you can do some cool things with these enumerators because you have complete control over how they return the data that they are enumerating over.

The next step is to see how the actual class to be enumerated provides its enumerator to the compiler.  When the compiler builds the for…in loop construct, it looks at the in part of the construct and thinks “Hey, I need an enumerator here, so I’ll call GetEnumerator”.  If the item in question indeed has a method called GetEnumerator, it calls it, and all is well.  If not, the compiler raises an error because the type in the in part of the for…in loop isn’t enumeratable. 

But of course, our TForInDemo class has such a method, and it is quite simple:

function TForInDemo.GetEnumerator: TForInDemoClassEnumerator;
begin
  Result := TForInDemoClassEnumerator.Create(FTheString);
end;

It merely creates and returns an instance of our enumerator, passing it the string value it is storing for the purpose of enumerating.   Pretty easy and straight forward, really.

Now that we’ve created all these classes, you can run the following code:

procedure DoStuff;
var
  ForInDemo: TForInDemo;
  C: Char;
begin
  ForInDemo := TForInDemo.Create('HelloWorld');;
  try
    for C in ForInDemo do
    begin
      Write(C, ',');
    end;
    WriteLn;

  finally
    ForInDemo.Free;
  end;
end;

 

IEnumerator<T> Interface

Now the above discussion talks a lot about specific methods that must be included as part of an enumerator, and as part of a class that wants to be enumerated.  And of course, that should immediately make you think “Interfaces!”.  And sure enough, there are some nice interfaces that fall out of this. (You knew I’d work interfaces into things here eventually, didn’t you.  Yes, you did.) 

Consider this interface:

type
  IEnumerator<T> = interface
  ['{DD445F01-975D-405E-BCC1-09D3E78CB0FF}']
    function GetCurrent: T;
    function MoveNext: Boolean;
    property Current: T read GetCurrent;
  end;

That should look awfully familiar.  It’s the exact two methods and one property needed to implement an enumerator – hence the name. 

I’ve declared this IEnumerator<T> interface myself, but the Delphi RTL includes a similar one in the System.pas unit. And at its base, IEnumerable<T> is all about implementing the GetEnumerator method.   

It leverages generics because the type of what is being enumerated doesn’t matter as far as the interface is concerned.  And remember when I said that a call to GetEnumerator could return an interface?  Well it can, and the compiler will happily use an IEnumerator<T> to implement the for…in loop.

Thus, your enumerators can implement this interface and your calls to GetEnumerator can return this interface, and you can add flexibility to how they are implemented.  Here’s an example:

  TStringEnumerator = class(TInterfacedObject, IEnumerator<Char>)
  private
    FIndex: integer;
    FString: string;
    function GetCurrent: Char;
  public
    constructor Create(aString: string);
    function MoveNext: Boolean;
    property Current: Char read GetCurrent;
  end;

  TInterfaceEnumeratorDemo = class
  private
    FTheString: string;
    procedure SetTheString(const Value: string);
  public
    constructor Create(aString: string);
    function GetEnumerator: IEnumerator<Char>;
    property TheString: string read FTheString write SetTheString;
  end;

Notice that the call to GetEnumerator returns an IEnumerator<Char> which is actually the individual type being iterated. In this case, the generic type needs to be the same type as the variable being returned in the for part of the for…in loop.  

This enables you to do the following:

procedure DoInterfaceStuff;
var
  InterfacedEnumerator: TInterfaceEnumeratorDemo;
  c: Char;
begin
  InterfacedEnumerator := TInterfaceEnumeratorDemo.Create('GoodbyeWorld');
  try
    for c in InterfacedEnumerator do
    begin
      Write(C, ',');
    end;
    WriteLn;
  finally
    InterfacedEnumerator.Free;
  end;
end;

 

Specialized Enumerators

The implementation of an enumerator is, as I mentioned, really simple.  But what if you wanted to get a little creative in the GetCurrent method?  After all, at that point you have complete control over what the enumerator returns.  In our simple case with characters and strings, what if we decided to, say, always return the upper case version of the character?  Or if we were iterating over integers, return the squares of the numbers in the collection?  That would be super easy, right? Well, yes, it would.

Consider this code:

  TForInDemoClassUpperCaseEnumerator = class(TForInDemoClassEnumerator)
  protected
    function GetCurrent: Char; override;
  end;
...
function TForInDemoClassUpperCaseEnumerator.GetCurrent: Char;
begin
  Result := UpCase(inherited GetCurrent);
end;

This class descends from TForInDemoClassEnumerator and overrides the existing enumerator for our demo class and returns the upper case of the character in question. 

If we wanted, we could return this class from our GetEnumerator call, but that would be sort of playing a trick on the user of our code. How about if we provide two different enumerators, and then make each available for enumeration in a for…in loop.  Surely that is possible, right?  Of course it is. 

First, we’ll look at the end result and then work our way backwards to see how it was implemented, because you have to play a little trick to expose more than one enumerator for a class:

procedure DoMoreStuff;
var
  C: Char;
  ForInExtraDemo: TForInDemoExtraIterators;
begin

  ForInExtraDemo := TForInDemoExtraIterators.Create('Greetings');
  try
    for C in ForInExtraDemo.AsUpperCase do
    begin
      Write(C, ',');
    end;
    WriteLn;
end;

This little routine will display the string “Greetings” as “G,R,E,E,T,I,N,G,S” in the console.  But note in the for…in loop that the actual class is not passed to the in clause, but a method that returns a “proxy” class that has the desired enumerator attached to it instead.  This is implemented as follows:

TUpperCaseEnumeratorProxy = class
  private
    FOwner: TForInDemo;
  public
    constructor Create(aOwner: TForInDemo);
    function GetEnumerator: TForInDemoClassUpperCaseEnumerator;
  end;
..
constructor TUpperCaseEnumeratorProxy.Create(aOwner: TForInDemo);
begin
  inherited Create;
  FOwner := aOwner
end;

function TUpperCaseEnumeratorProxy.GetEnumerator: TForInDemoClassUpperCaseEnumerator;
begin
  Result := TForInDemoClassUpperCaseEnumerator.Create(FOwner.TheString);
end

This is just another class that can be enumerated – it has a call to GetEnumerator – and thus be returned by a method call on our “real” enumerating class.  It returns an instance of an enumerator called TForInDemoClassUpperCaseEnumerator which we looked at above.  So, if you want to iterate over the upper case version of the strings, you call it as we did in the DoMoreStuff method above.  The trick here is that instead of iterating over the class itself, you iterate over the proxy class using ForInExtraDemo.AsUpperCase.  It’s a neat little trick, eh?

Thus, the enumerating class becomes:

  TForInDemoExtraIterators = class(TForInDemo)
  private
    FUpper: TUpperCaseEnumeratorProxy;
  public
    constructor Create(aString: string);
    property AsUpperCase: TUpperCaseEnumeratorProxy read FUpper;
  end;
...
constructor TForInDemoExtraIterators.Create(aString: string);
begin
  inherited Create(aString);
  FUpper := TUpperCaseEnumeratorProxy.Create(Self);
end;

Conclusion

So, that should give you a little insight into what happens with for…in loops and  how you can create classes that participate automatically.  I’m working towards never using the old for I := 0 to Count –1 do; construct, and making my classes enumeratable.

The code for this article with further examples can be found with my demo code on BitBucket.

Stuff I’ve Been Reading And Watching

By Nick at January 12, 2013 01:50
Filed Under: Delphi, General

Flotsam and Jetsam #73

By Nick at January 07, 2013 11:51
Filed Under: Flotsam and Jetsam, Delphi
  • Do you think it is safe to say that this map is a pretty good illustration and approximation of world-wide Delphi use?  It’s a map of visitors to http://www.spring4d.org.  There are even Delphi users in Iceland! The information you get from this Google Trends search also reveals some interesting geographical information.  It seems that there are a lot of Delphi developers in Russia.  (These types of searches are complicated by the fact that Delphi is also a major auto parts company…)
  • The new year means an updated look at the TIOBE Index!  And guess what language is #1 for 2012?  C.  Not C++, C.  It’s moved past Java as the most popular language.  That’s kind of a surprise to me, anyway.  Delphi continues to hold it’s spot in the “A” language at #15.  They seemed to have combined “Delphi” and “Object Pascal”, but put “Pascal” in its own category. This makes no sense to me, but oh well.  If you combine the numbers all up, “Delphi/Object Pascal/Pascal” ends up at number 11 ahead of Ruby. Completely respectable if you ask me. Another surprising thing to me on the index is how low Javascript ranks. 
  • New Delphi Blog of the Week comes from Francois Piette
  • The Delphi Developers Community on Google Plus is quite active – if you aren’t a member, you should join up and contribute.  Maybe you’ll be the 1000th member!
  • New Delphi Components of the Week:   Chrome Tabs – It’s open source, too.  Pretty nice. 
  • Question of the Day: Arduino or Raspberry Pi?  Why?

Loop Less with IEnumerable and Spring for Delphi

By Nick at January 06, 2013 10:57
Filed Under: Delphi, Software Development

I rave about the Delphi Spring Framework.  But I think my attention to the Dependency Injection Framework – which is only part of it -- has made you guys think that the two are synonymous.  Not true – Spring4D is more than just a Dependency Injection container.  In fact, there is a wealth of other stuff to be found in Spring4D.

Inspired by this StackOverflow question and a thread in the newsgroups, I thought that I’d write an article about a very powerful but not so well known (apparently) feature of Spring4D – IEnumerable<T> and the accompanying container interfaces and classes.

So the StackOverflow question basically asks this: How do I find out the maximum value of an integer in TList<integer>?

Well, the first thing you might do is use a for loop to check each item, and save each one as it gets larger.  Or if you were really tricky, you’d use a for…in statement to find it.  That’s the “straight-up” way to do it.

But that isn’t the real answer to the StackOverflow question.  The real answer is this:

program ListEnumerableDemo;

{$APPTYPE CONSOLE}

{$R *.res}

uses 
    System.SysUtils 
  , Spring.Collections;

var 
  List: IList<Integer>; 
  Enumerable: IEnumerable<integer>;

begin 
  try 
    List := TCollections.CreateList<integer>; 
    List.AddRange([1,6,2,9,54,3,2,7,9,1]);

    Enumerable := List; 
    WriteLn(Enumerable.Max); 
    ReadLn; 
  except 
    on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
  end; 
end. 

 

Now that looks quite a bit different than the code you were thinking of, I’ll bet.   There doesn’t even appear to be any looping going on at all.  There is in the background, but it’s all been abstracted away for you.  You want the maximum value to be found in the list?  Just ask for it.  Cool.

The key part above, of course, is the use of two things.  First, the IList<T> – an interface to a generic list – and secondly, the IEnumerable<T>.  Both of these types are provided by the Delphi Spring Framework.  Both are defined in the Spring.Collections.pas unit.  That unit contains a complete group of collection interfaces – IList<T>, IStack<T> ICollection<T>, etc. – as well as the definition of IEnumerable<T>. 

I’d recommend that you consider using Spring.Collections.pas instead of the Generics.Collections.pas unit which comes with Delphi.  First, it exposes all of the collection types as interfaces, and you should know by now that you should be coding against interfaces and not implementations.  Secondly, each of the types supports the IEnumerable<T> interface, meaning you have the power of this great interface on all of your collections.

We’ll tackle those two things in order.

Spring Collections

The Spring.Collections.pas unit is all you need in your uses clause to avail yourself of all that the Spring collections library provides.  The unit includes the following interfaces along with a class to provide easy access to implementations of these interfaces:

Interface Description
ICollection<T> A Collection is a group of items in no particular order.  You can't insert items into a specific location in a collection, only add or remove them.  A collection can’t be sorted because it has no order.
IList<T> A list is a group of items in a particular order.  Items can be sorted and inserted in particular locations.
IDictionary<TKey, TValue> A dictionary is a data structure that allows you to “look up” items.  Each entry takes a key and a value, and values can be looked up by asking for it via the item’s key.  This is a useful data structure, as any type can be uses as the index, and any type can be stored for lookup.
IStack<T> A stack is a First In, Last Out data structure. Think of a spring-loaded stack of plates at the cafeteria – you “push” plates onto the stack, and then “pop” them off in reverse order.
IQueue<T> A queue is a First In, First Out data structure.  Think of an ordinary line that you wait in, or a tube in which items are inserted at one end and taken out on the other.
ISet<T> A set is a data structure involving membership.  Items are either in the set or out.  A set’s methods allow you to determine the intersection, union, or overlap with any other container.

 

All of these types should be familiar to you – if not, you can certainly read up on them via Google.  The important part is that they are all generic (though there are non-generic types with store TValue as well) and they all implement IEnumerable<T>.

The unit also provides a class called TCollections which has nothing but class methods that return instances of the types listed above.  These methods act as proxies for the constructors of the implementing types.  You can create your own instances if you like, but for the most part, TCollections will do the job of getting an implementation of whatever container interface you want.  For instance, if you want to get a hold of a dictionary, you can do the following:

program ListEnumerableDemo;

{$APPTYPE CONSOLE}

{$R *.res}

uses 
    System.SysUtils 
  , Spring.Collections;

var 
  List: IList<Integer>; 
  Enumerable: IEnumerable<integer>;

begin 
  try 
    List := TCollections.CreateList<integer>; 
    List.AddRange([1,6,2,9,54,3,2,7,9,1]);

    Enumerable := List; 
    WriteLn(Enumerable.Max); 
    ReadLn; 
  except 
    on E: Exception do 
      Writeln(E.ClassName, ': ', E.Message); 
  end; 
end. 

The example above uses TCollections.CreateList<integer> to get an implementation of the IList<T> interface.

The implementations are all in units named Spring.Collections.Stack.pas and the like, but the Spring.Collections.pas unit exposes almost everything you need, and so as a rule, you should only need it in your uses clauses to take advantage of these powerful containers.

 

IEnumerable<T>

Those of you who also use .Net are familiar with IEnumerable already, but perhaps you didn't know that the same power was available to you in your Delphi code.  For those of you not familiar, you are in for a treat.

The IEnumerable<T> interface is implemented by all of the classes discussed in the previous section, and so any of them can be accessed as an IEnumerable<T>. 

Here is the declaration of IEnumerable<T>:

IEnumerable<T> = interface(IEnumerable)
    function GetEnumerator: IEnumerator<T>;
    function AsObject: TObject;
    function TryGetFirst(out value: T): Boolean;
    function TryGetLast(out value: T): Boolean;
    function First: T; overload;
    function First(const predicate: TPredicate<T>): T; overload;
    function FirstOrDefault: T; overload;
    function FirstOrDefault(const defaultValue: T): T; overload;
    function FirstOrDefault(const predicate: TPredicate<T>): T; overload;
    function Last: T; overload;
    function Last(const predicate: TPredicate<T>): T; overload;
    function LastOrDefault: T; overload;
    function LastOrDefault(const defaultValue: T): T; overload;
    function LastOrDefault(const predicate: TPredicate<T>): T; overload;
    function Single: T; overload;
    function Single(const predicate: TPredicate<T>): T; overload;
    function SingleOrDefault: T; overload;
    function SingleOrDefault(const predicate: TPredicate<T>): T; overload;
    function ElementAt(index: Integer): T;
    function ElementAtOrDefault(index: Integer): T;
    function All(const predicate: TPredicate<T>): Boolean;
    function Any(const predicate: TPredicate<T>): Boolean;
    function Contains(const item: T): Boolean; overload;
    function Contains(const item: T; const comparer: IEqualityComparer<T>): Boolean; overload;
    function Min: T;
    function Max: T;
    function Where(const predicate: TPredicate<T>): IEnumerable<T>;
    function Skip(count: Integer): IEnumerable<T>;
    function SkipWhile(const predicate: TPredicate<T>): IEnumerable<T>; overload;
    function SkipWhile(const predicate: TFunc<T, Integer, Boolean>): IEnumerable<T>; overload;
    function Take(count: Integer): IEnumerable<T>;
    function TakeWhile(const predicate: TPredicate<T>): IEnumerable<T>; overload;
    function TakeWhile(const predicate: TFunc<T, Integer, Boolean>): IEnumerable<T>; overload;
    function Concat(const collection: IEnumerable<T>): IEnumerable<T>;
    function Reversed: IEnumerable<T>;
    procedure ForEach(const action: TAction<T>); overload;
    procedure ForEach(const action: TActionProc<T>); overload;
    procedure ForEach(const action: TActionMethod<T>); overload;
    function EqualsTo(const collection: IEnumerable<T>): Boolean; overload;
    function EqualsTo(const collection: IEnumerable<T>; const comparer: IEqualityComparer<T>): Boolean; overload;
    function ToArray: TArray<T>;
    function ToList: IList<T>;
    function ToSet: ISet<T>;
    function GetCount: Integer;
    function GetIsEmpty: Boolean;
    property Count: Integer read GetCount;
    property IsEmpty: Boolean read GetIsEmpty;
  end;

That’s a lot of cool stuff, right?  Many of the methods here are pretty clear -- it's pretty obvious what the Min and Max methods do. But some of the others are a bit trickier.  You can get all of the items.  You can get the First and Last items.  You can get the first x number of items.  You can get the items back out as a List, an Array, or a Set.  And most powerfully, you can get any particular group of the items out using a predicate.

Predicates

What is a predicate?  A predicate is an anonymous function (or any function, really, but in our case it is an anonymous function) that takes a single const parameter of the type in question and returns True or False.

 TPredicate<T> = reference to function(const value: T): Boolean;

It is used with some of the methods of IEnumerable<T> to answer this simple question:  In or out?  If the predicate is true, then the individual item is “in”, or included.  If it is “out”, then the predicate will return False.  So if you want to get all the items in a list strings that contain the letter ‘z’, then you can do the following:

function ContainsLetterZ: IEnumerable<string>;
var
  List: IList<string>;
begin
  List := TCollections.CreateList<string>;
  List.AddRange(['zoo', 'park', 'city', 'town', 'museum', 'jazz festival']);

  Result := List.Where(function(const aString: string): Boolean
                     begin
                       Result := Pos('z', aString) > 0;
                     end);
end;

The above uses the Where method to determine items that should be returned as part of a new IEnumerable<string>.  The above is saying “return to me an enumerable item where all the strings in the list have ‘z’ in them.”

You can do similar things with the TakeWhile method, which returns items from the start of the list as long as the predicate is True, and stops once the predicate is False.   You can determine if a given container has or doesn’t have a given element.  You can Skip over a given number of elements and take the rest.  You can use a predicate to SkipWhile a certain thing is true, and then return the rest once the predicate returns True  Basically, once you have a reference to a collection or any IEnumerable<T> instance, you can get out of it pretty much anything you want.

Something to consider:  If you have a nicely composed class that includes a private IList<T> which gets exposed through proxy methods, then you might want to expose access to the items via a property of type IEnumerable<T> instead of exposing the actual list itself.

And the real power gets unleashed with the very powerful ForEach methods.  Folks have always pined for the lovely ForEach since the days of Borland Pascal’s old TCollection object, and now it’s back in full force, leveraging the power of anonymous methods.  Thus, you can have a collection and do what you please with the items.  Here is a simple example of just outputting them to the console window, but you can have your TAction<T> do anything at all that you like for each (sorry) element in the container.

procedure SimpleForEachDemo;
var
  List: IList<integer>;
  Action: TAction<integer>;
  i: Integer;
begin
  Action := procedure(const aInt: integer) begin Writeln(Format('This number is: %d', [aInt])); end;

  List := TCollections.CreateList<integer>;
  for i := 1 to 10 do
  begin
    List.Add(Random(100));
  end;

  List.ForEach(Action);
end;

So, basically you have a lot of untapped power there in Spring.Collections.pas, eh?  The use of IEnumerable<T> and predicates ought to transform your code and change the way you look for things in lists and collections.  If you aren’t using these powerful tools yet, I strongly recommend that you add them to your tool chest.

I’ve written a pretty thorough example application for IEnumerable<T> and put it up on BitBucket.  I also have some pretty simple examples showing predicates at work.

Remember, the Delphi Spring Framework is more than a Dependency Injection container.  And there’s more to it than the container classes as well.  I strongly recommend that you start treating Spring4D like part of the Delphi Runtime Library.  Heck, I wish Embarcadero would do just that.

Flotsam and Jetsam #72

By Nick at January 04, 2013 11:21
Filed Under: Delphi, Flotsam and Jetsam, Software Development
  • Am I weird?  One of the first things I do when I install Delphi is to turn off Brace Matching and Line Highlighting.  I find both of these features incredibly distracting, particularly the Brace Highlighting, which makes it impossible to see where the caret is in the text. 
  • This article by Hal Berenson should make interesting reading for Delphi folks interested in the economics of development tool vending and the business models around them.  Delphi isn’t mentioned, but it does discuss the changing business model of Visual Studio from within Microsoft and how Adobe’s tool business put pressure on MS and actually changed how they did business.  MS’s  Interesting stuff.
  • I love Twitter and try to tweet pretty frequently (I’d be honored if you followed me).  One of the fun part of tweeting is seeing the creative and interesting use of hashtags.   One current hashtag that is going around and that is of interest to us Delphi developers is #code2012.  In it, folks are putting the names of the languages that they coded in during the past year.  Someone has a nice graphic that shows the relative popularity – and Delphi isn’t doing too badly.  I just tweeted to help make that Delphi circle just a little bigger.  Winking smile
  • Holy cow, I feel like I did when Buffy ended – stunned and saddened.   Žarko Gajić is moving on from his position as the guide for About.Com Delphi.  Žarko has been doing that job for 15 years, and I’m willing to bet that his site is as common a search result as any in the community.  Well done, Žarko, and good luck in your future, Delphi-related endeavors.  And hey, the door is open – anyone willing to step into Žarko’s shoes?

My Book

A Pithy Quote for You

"When buying and selling are controlled by legislation, the first things to be bought and sold are legislators."    –  P. J. O'Rourke

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.