Amazon.com Widgets All posts by nick

Delphi XE6 is Here

By Nick at April 15, 2014 11:17
Filed Under: Delphi, Tech Stuff

Delphi XE6 has been released.  There are reportedly over 2500 bug fixes in it, which is quite a few and quite in keeping with the QPS (Quality, Performance, Stability) plan they’ve discussed.  Probably the best place to find out what is in the release is in the DocWiki’s What’s New Page

 

And if you are ready to make the move, you can click on the banner below and purchase:

Thank you ADUG

By Nick at March 30, 2014 16:43
Filed Under: Delphi

I had a great time at ADUG 2014 this year.  I'm grateful to the group for their gracious hospitality.  They took very good care of me, and I'm thankful.  I was honored to sign all of the copies of Coding in Delphi that I did, and was pleased to see so many of them there. :-)  I presented on Dependency Injection and Patterns in Delphi both in Melbourne and Brisbane.  I think that talks were well received.  Overall, I love going to Australia and was honored to be asked.  Thanks, ADUG. 

Flotsam and Jetsam #82

By Nick at March 18, 2014 17:26
Filed Under: Delphi, Flotsam and Jetsam
  • Yay!  Flotsam and Jetsam is back!  Did you miss it?
  • Okay, some really interesting things going on with Appmethod.  Appmethod is Embarcadero’s new cross-platform development tool.  For you Delphi/RADStudio types, it appears to be a FireMonkey only IDE with some new connectivity that will be of interest only to mobile developers.  In other words, it is a new aimed squarely at new customers and not “us”.  Anyway, David I has a bunch of links on his blog, including a bunch of nice press coverage.  This new offering appears to me to be aimed squarely at the Xamarin space, as the pricing is very similar.  Should be fun to see how this plays out. 
    • As a side note – if you are a Delphi/RAD Studio person, this product is not for you, and so you need not be upset if the offering and the pricing is not to your liking.  Stick with RAD Studio and cheer on the product as Embarcadero expands into a new market.  This is a good thing – Embarcadero is branching out to reach into the very hot, growing, and important mobile development market.  This is a new, exciting entry into that nascent market.  I for one am hoping for great success for Appmethod, because that can only be good for Embarcadero and thus Delphi.  It represents a whole new revenue stream for the company, and what is good for Appmethod will be good for Delphi. 
  • Some interesting things to note that are going on with Appmethod:
    • You can report bugs not in QualityCentral, but in a public JIRA repository.  That is very interesting.
    • In addition, there appears to be a completely new Embarcadero Community website.  Appmethod is the only app represented there so far, but the rest of the products can be far away.
    • Part of the new community site are public forums. Looks like you can earn points and rank for being an active participant.  I wonder what will happen to the existing ones that support NNTP. I know many folks over there will give up their NNTP readers when you pry them from their cold, dead fingers.  Again, should be interesting.
    • Here’s the Appmethod EULA online for everyone to read.
  • Book Update: As I hope you know, my book is available two ways – in electronic form to people who purchase XE5, and in paperback form from CreateSpace and Amazon.  Many of you have purchased – more than I had hoped, in fact, and I’m really greatful.  Thanks very much, really.  It’s really an honor to have someone buy your book.  If you have purchased the book, I sure would appreciate a review on Amazon – good or bad! – as that really helps other people decide whether to buy.  Thanks to David Schwartz who was the first to do a review on Amazon.
  • Kind of lost in the shuffle a bit with Appmethod and all is the fact that Embarcadero purchased Erwin From CA Technologies. I find this to be a really interesting move, because when I was at Embarcadero, Erwin was “the enemy” – the product that ER Studio competed most strongly with.  Embarcadero now has two tools that basically do the same thing. I guess they won’t need this page and whitepaper anymoreWinking smile It will be interesting to see how that plays out. 

Nick in Australia

By Nick at March 10, 2014 10:23
Filed Under: Delphi

I’m really excited to return to Australia and speak at the Australian Delphi Users Group.  They were kind enough to invite me, and so off I go next week to Melbourne and Brisbane to talk about Dependency Injection and Design Patterns.  If you are in Australia and not going, I’m guessing that it’s not too late to sign up. If you are going, I’m looking forward to seeing you again or meeting you for the first time.  I’m also looking forward to a little summer weather after this crazy winter in Pennsylvania.  Winking smile

Coding in Delphi Now Available in Print

By Nick at February 22, 2014 10:54
Filed Under: Delphi, Software Development

My book, "Coding in Delphi" is now available in print.  This is pretty cool. You can get it from CreateSpace or Amazon.  I'm grateful for every order. 

It seems very strange to have my own entry for sale on Amazon.  Writing a book is a lot of work, but I will say, it's quite satisfying to hold the book in your hand and see your name on Amazon.com.  :-)

I'd also be very grateful for book reviews on Amazon.  If you like the book, please let people know.  And if you don't like it, write a review and say why.  Either way, I'll appreciate your honest assessment.  You can write the review right from the Amazon order page.  

And again, I'm grateful to all of you who have had so many nice things to say, who helped edit the book, and who make the Delphi community so great.

I’m Speaking at EKON 17

By Nick at September 05, 2013 12:07
Filed Under: Delphi, Personal

Hey, I’d be delighted if you came to see me speak at the EKON 17 conference in Cologne, Germany the first week in November.

Ekon17_2013_fullsize_19917_v2

I’ll be giving two regular talks on Unit Testing and Dependency Injection, as well as an all day tutorial on advanced programming topics such as Generics, Anonymous Methods, RTTI, Virtual Interfaces, and more.  The conference will be a great time with such well-known and respected names as Ray Konopka, Cary Jensen, Jeroen Pluimers, Daniel Wischnewski and more.  Marco Cantu from Embarcadero will also be there.

I’m really looking forward to going.  You should go, too.

The Delphi Unit Test Project

By Nick at August 17, 2013 16:02
Filed Under: Delphi, Unit Testing, Software Development

In a previous post, I humbly suggested that Embarcadero publish their unit tests for Delphi.  I still think it is a good idea, but I understand if they don’t do it.  They do have a lot to do.

So I thought – after suggestions from folks that read the post, including Kenneth Cochran – that it would be a good idea to just go ahead and start our own community project.  So I did.

The Delphi Unit Tests Project

This is a pretty straight-forward project – it is merely a set of unit tests for Delphi’s RTL.  You can find out the basics on the home page of the wiki, where you’ll also find further information about writing tests, etc.  It’s a wiki, so it will continue to be expanded. I’m kind of weird in that I actually enjoy writing unit tests, so I’ve been adding tests over the last week or so.

This is a community project based on Mercurial.  That means that anyone can fork it, add tests, and then submit a pull request.  We’ve already had four or five submissions, and I’m really appreciative.  It’s quite easy to contribute, and you can write tests for anything you like.  Any submitted tests must pass, of course.

We are also using the new Delphi unit testing framework, DUnitX.  It is still a bit rough around the edges, but hopefully this will be an impetus to get it fully up to speed.  I’ve volunteered to write the GUI runner, but there are some architectural issues that need to be taken care of.  Right now, you can output to NUnit xml and the console.  DUnitX is attribute based and really easy to use.

Things I’d  like to eventually get done:

  • I’d like to get at least one test for everything we can in the RTL.
  • I’d like to figure out a way to have tests written for QualityCentral reports.  The tests could “pass”, proving the bug exists, and then when they “fail”, that could show that the bug has been fixed. 
  • I’d love to see our tests eventually get integrated into the Embarcadero internal build.  That would be really cool.

In any event, come join the cause and write a test.  Even one single test would be fine!

Produce More, Consume Less: A year and a half later

By Nick at July 28, 2013 16:31
Filed Under: Personal, Delphi, General

On January 1, 2012 – a year and a half ago – I wrote the this post called “Produce More, Consume Less”.  In it I discussed a bunch of stuff that I wanted to do in the coming year.  I thought it might be fun to review and see how I am doing on those things:

Write a substantive post on my blog once a week.

I did well with this for a while, but recently, I haven’t blogged much because I’ve been working on my book.  (See below).  In addition, 2012 ended up being a difficult year for the Hodges household, and so the blogging didn’t get done as much as I would have liked.  However, I think I have posted a pretty good chunk of content over the last year and a half.

Find an open source project and work on it.

Here I have fallen down.  I’ve wanted for a long time to write /// documentation for the Spring Framework, but I haven’t really done that.  I have created a good collection of Delphi code demos on BitBucket, but I’m not sure we can really call that an “open source project”.  I will put effort into the Spring for Delphi documentation moving forward, I promise.

I’m going to get off my butt and walk.

I did…okay here.  I walked a lot with my wife.  Recently, however, this has tapered off quite a bit, and I’m sorry to say that I’m as heavy as I’ve ever been.  However, in just the last two days, I’ve started a determined effort to start running again.  I ran track and cross-country in college (though you can tell it was a very, very long time ago just by looking at me) and I’d like to be a runner again.  I’m determined this time.  We’ll see.  Actually, I have to because if I don’t, I’m headed for a heart attack.  Seriously.   

I’m going to write a book on coding in Delphi.

Well, I didn’t get it done in 2012, but I’m currently working hard on it and hope to have it done this year instead.  I’m nearly done with all the chapters for the first draft, and am looking more closely into how to get a cover, get it ready for publishing, etc.  I’m setting my sites on publishing it by the end of the year.

I’m going to be deliberate and purposeful in what I read. 

I think I have done pretty well here.  I made a list of books that I wanted to read and have read them, both novels and technical books. (I got an Amazon Kindle Paperwhite for Christmas, and I’ve read my books on it almost exclusively)   I’ve read a lot, and have a good list of “to read” books.  On the Internet side, I’ve pared down my collection of RSS feeds quite a bit, and spend time reading only those that are really important (like the blog of my wife and proofreader, ipaintiwrite). By the way, with the demise of Google Reader, I’ve switched over to The Old Reader for tracking my RSS feeds.

I’m going to be deliberate and plan any [TV and Movie] watching I do. 

Here I’ve done very well.  I don’t watch much TV anymore at all, and when I do, I deliberately choose what to watch and do so.  For instance, I recently finished up “Orange is the New Black” on Netflix, having decided deliberately to watch it.  I also watched “House of Cards”.  I can’t remember the last time I just sat down and randomly picked something to watch on TV.  As for Movies, I’ve seen most of the blockbusters in the theatre and watched almost no movies on DVD, Netflix, etc.  I’m pleased with how this is going.

I’m going to remove FreeCell from my phone.

I did this, as well as removed all other games from my phone. Other than playing Words with Friends at lunch with my co-workers (we are pretty obsessive about it), I’ve done really well here. I have spent very little time playing games, and when I have, it’s  been with my son for some good bonding time.

I’m going to spend time selling stuff on eBay.

This has been average.  I have sold some items, as well as donated a lot of things to charity.  I still have stuff that I’d like to sell, but haven’t really made a big dent in the large amount of “stuff” that I own.  I’d like to have less stuff, and so I’ll have to get after this.

Overall, after a year and a half, it’s not bad, but not great.  Losing weight, getting in shape, and publishing my book are at the top of the list going forward. 

In Which I Argue That Embarcadero Should Open Source Their Unit Tests

By Nick at July 27, 2013 13:27
Filed Under: Software Development, Delphi, Unit Testing

All good developers write unit tests.  The Delphi team is no different.  The team has a suite of unit tests for the RTL and a very, very large set of tests for the compiler.  The tests for the RTL are, to a large degree, DUnit based.  The compiler tests are a bit different, as they date back well before DUnit even existed.  They are a set of console applications that write out PASS or FAIL to the standard output depending on whether the test passed or failed. I believe that this suite of tests also tests a lot of the lower level RTL.   I know the QA team doesn’t like to test the RTL using a tool that depends heavily on the RTL itself.

So anyway, this suite of tests exists.  They get run constantly as part of a continuous integration process at Embarcadero.  And the suite gets expanded as time goes by.  When I managed the R&D team, I even contributed to the test suite myself.

But given that you can’t ever have enough unit tests, and that like all companies, Embarcadero has limited resources, the test suite doesn’t expand fast enough.  (Actually, I suppose no test suite expands fast enough, right?)

So I have a plan:  Embarcadero should open source their unit test suite and accept inputs from the community. 

Here’s why I think they should do that.

  • It will enable the community to expand the suite of tests -- As I noted above, every unit test suite is too small and doesn’t cover enough of the possibilities.  Embarcadero can continue to expand their test suite by themselves, or they can harness the power of the community to write tests.  The current public code repositories allow for forking and pull requests, and it would be dead simple for me or anyone to fork the project, add tests, and then issue a pull request.  This will allow people to write tests for their favorite parts of the RTL, and as will be discussed below, allow them to report bugs by writing tests that should pass but fail.  Many hands make for light work.
  • It will help build customer confidence in the quality of the Delphi RTL –A public facing, expanding suite of tests with community participation will build confidence in the quality of the product.  If people know and see that the RTL and the compiler are bathed in a complete, growing suite of tests, they’ll feel better about the product.  If they see how thorough and complete the suite is, they’ll know that the product they use is solid.
  • It will help people learn the proper way to use the product – One of the things that unit tests can do is to provide a sort of “documentation” for the things being tested.  They can illustrate the proper way to use the RTL code, and show customers the things that can be done that they might not have known about.  A nice suite of tests for a new RTL unit or class will help customers see how to use the class and what it is supposed to do.
  • It will encourage the team at Embarcadero to write more tests – When Lee Ioccoca took over a failing Chrysler in the late 1970s, one of the first things he did was throw down the gauntlet in front of the company: He would give all buyers a 10 year, 100,000 mile warrantee for the car.  That was an impetus to the entire company to improve quality.  Publishing the compiler and RTL test suites will have the same effect on the team at Embarcadero.  If the tests are public, then the team will feel the pressure (the good kind) to ensure that any new code has tests.  The community won’t want to see a new RTL unit without any tests (Will we, guys, right?)
  • It will enable people to report bugs in a better and more useful way – The easiest kind of bug to fix is one with a failing unit test.  If things got really rolling, customers could write unit tests that reveal bugs, Embarcadero could fix the bugs, and then the test would be a true regression test.  That would be awesome.  Customers could even use the tests to suggest fixes.  Having all the tests would enable them and Embarcadero to be more confident in a suggested fix.

I could think of some objections that they might have.  Here are some of those objections, along with reasons why those objections should be ignored. 

  • “The code isn’t ready for public consumption” – No one cares.  Seriously.  Anyone in the community that complains about the quality of the tests or lack of coverage can get to work and fix things.  No complaining if you aren’t helping.  The tests are probably better than most, and even if they are bad, they’ll get fixed. 
  • “It’s too much work for us” – No it isn’t. “We don’t have the time.” Yes you do.  It shouldn’t take more than an hour to gather the tests and post them on BitBucket or GitHub.  (Please, not SourceForge.  And by the way, whatever you do – for the love of Baby Elvis  -- don’t post it in Subversion. Only Git or Mercurial will allow for the community involvement you want and need.).  Plus, that small investment will enable an army of developers to submit pull requests with new tests.  Those tests can be quickly reviewed and accepted.  It will take less time to accept tests than it will to write them.  Shoot, you could even enlist trusted community members to help out.  I can think of at least one Embarcadero MVP (cough, me, cough) that would be willing to help be a gatekeeper.
  • “This is internal, private stuff that we shouldn’t be sharing”.  No, this is exactly the kind of stuff you should be sharing.  There are no trade secrets here.  The tests are useless without the products.  There is nothing to be lost by doing this, and much to be gained.  This is the kind of thing that a modern, forward-looking company would do.  Be a leader.  Be brave and bold!

I thought long and hard for reasons why Embarcadero shouldn’t open source their tests, and I couldn’t think of any.  Seriously, I can’t think of a downside here.

So how about it, guys?

Service Locator is Indeed an Anti-pattern

By Nick at June 05, 2013 21:20
Filed Under: Delphi, Software Development, Unit Testing, Patterns

As you know, I love Dependency Injection.  I wrote a whole series of articles on it using the Spring for Delphi framework, and in my previous position instituted its pervasive use in the large project there. I’m scheming to integrate it into the legacy app I work on now.  I bought and read the definitive book on the subject:

But there was always one thing that bugged me -- In Mark Seemann's book and in this article (Service Locator is an Anti-pattern) he argues against the use of a ServiceLocator – that is, a class that grabs instances out of the DI Container and hands them to you for your use.  I never really agreed, as I didn’t see any other way to do it – of course you needed to grab instances out of the container via a Service Locator pattern.  How else would you do it? I mean, you can do Constructor Injection and all, but at some point you need to grab an instance of something, right?  I had read his stuff, read the comments and arguments on the topic, but was never really persuaded.  But then again, maybe I was missing something.  The question of “how” always held me back.

Well, I was working on some demo code for my book, and out of the blue, all of a sudden, it hits me:  Seemann is right.  The ServiceLocator is an anti-pattern, mainly because it is pretty much unneeded. 

Here’s what happened. 

First thing: if you go to my demo code on BitBucket, you’ll see a Dependency Injection demo there that uses the ServiceLocator to grab instances of registered classes.  It’s cool – you can understand the basics of DI by looking at it.  You can properly decouple the code and end up with nothing but a unit of interfaces in your uses clause.  Nice.  I even did a CodeRage presentation using this basic code.  That code illustrates how you can use a DI Container and the ServiceLocator to create loosely coupled code.  No worries.  However, you’ll notice that the calls to the ServiceLocator kind of become replacements for calls to Create

Only you can do the same thing with no ServiceLocator calls. 

Second:  The Delphi Spring Container has a set of methods that I confess I never quite understood:

 

    function InjectConstructor(const parameterTypes: array of PTypeInfo): TRegistration<T>; overload;
    function InjectProperty(const propertyName: string): TRegistration<T>; overload;
    function InjectMethod(const methodName: string): TRegistration<T>; overload;
    function InjectMethod(const methodName: string; const parameterTypes: array of PTypeInfo): TRegistration<T>; overload;
    function InjectField(const fieldName: string): TRegistration<T>; overload;

 

These methods allow you to inject (duh) different items into your classes and automatically instantiate them as a result.  I knew they were there, I knew that they were useful, but I never understood completely why they were in there.  You could pretty much get along without them because you had the ServiceLocator to grab anything you need.  

I was reading Mark Seemann’s book again, and reading about how you should be using constructor injection everywhere, and how you need to push the creation of your component graph all the way back to the composite root. In Delphi, that means all the way back to the first line of the DPR file.  And if you do that, you could end up with this monster constructor that requires every single class your application needs.  And it was this notion that made me think “The ServiceLocator is necessary to get rid of that huge constructor.”

So I confess I never quite got it. 

But yesterday, I’m working on sample code for my book, and of course, I have to show how the above methods work.  I’m working up demos (I’ll show a simple one below that illustrates the whole thing) and it hits me:  The key to the whole notion of a ServiceLocator being an anti-pattern lies in what these five methods can do. 

And basically what they can do is this:  They can cause the creation of every single class needed for your application during the registration process.  They can completely eliminate the need for you to ever call the ServiceLocator (with one exception, discussed below) because if you can call the ServiceLocator, you can use these methods to register the connection between what you need the ServiceLocator for and the registration process.

Put another way, every call to the ServiceLocator can be replaced by a registration call.  You don’t need the ServiceLocator because the registration process alone is enough.

So I think a simple example is in order.  I’ll try to keep it short and sweet. 

Consider the following unit of code:

unit uNoServiceLocatorDemo;

interface

uses
      Spring.Container
    , Spring.Services
    , Spring.Collections
    ;

type
  IWeapon = interface
  ['{0F63DF32-F65F-4708-958E-E1931814EC33}']
    procedure Weild;
  end;

  IFighter = interface
  ['{0C926753-A70D-40E3-8C35-85CA2C4B18CA}']
    procedure Fight;
  end;

  TBattleField = class
  private
    FFighter: IFighter;
  public
    procedure AddFighter(aFighter: IFighter);
    procedure Battle;
  end;

  TSword = class(TInterfacedObject, IWeapon)
    procedure Weild;
  end;

  TKnight = class(TInterfacedObject, IFighter)
  private
    FWeapon: IWeapon;
 public
    constructor Create(aWeapon: IWeapon);
    procedure Fight;
  end;

implementation

{ TBattleField }

procedure TBattleField.AddFighter(aFighter: IFighter);
begin
  FFighter := aFighter;
end;

procedure TBattleField.Battle;
begin
  WriteLn('The Battle is on!');
  FFighter.Fight;
end;

{ TKnight }

constructor TKnight.Create(aWeapon: IWeapon);
begin
  inherited Create;
  FWeapon := aWeapon;
end;

procedure TKnight.Fight;
begin
  WriteLn('The knight swings into action!');
  FWeapon.Weild;
end;

{ TSword }

procedure TSword.Weild;
begin
  WriteLn('"Swoosh" goes the sword!');
end;

initialization

  GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
  GlobalContainer.RegisterType<TKnight>.Implements<IFighter>('knight');


end.

 

Here we have some classes that are all nicely decoupled.  Our registrations are neatly named.  The classes use constructor injection to ask for their dependencies, and the TKnight and the TSword are nicely registered, just waiting to be grabbed and used in a decoupled way using the ServiceLocator.  All is great.  And then in order to actually have our cast of characters do anything, you might do something like this:

 

procedure FightBattle;
var
  Battlefield: TBattleField;
  TempKnight: IFighter;
  TempSword: IWeapon;
begin
  Battlefield := TBattleField.Create;
  try
    TempKnight := ServiceLocator.GetService<IFighter>;
    TempSword := ServiceLocator.GetService<IWeapon>;
    TempKnight.Weapon := TempSword;
    Battlefield.AddFighter(TempKnight);
    Battlefield.Battle;
  finally
    Battlefield.Free;
  end;
end;

 

You need a knight and a sword?  Well, just call the ServiceLocator, grab the sword, arm the knight, add him to the battle, and off it goes.  You get this:

image

 

It all works, and it is all decoupled.  But you are still using the ServiceLocator

The argument against the ServiceLocator is pretty simple: It’s a singleton, singletons are global variables, and global variables are bad. (That’s a gross oversimplification – read the article and the comments for a better discussion….) Plus, if you don’t need it, why use it?

Well, you don’t need it.  Watch.

First thing to note is that Seeman says you should have one call to the ServiceLocator at the very root of your application.  You get one shot.  We’ll see that one shot below.

Second, let’s change how we register our classes and interfaces: 

 

  GlobalContainer.RegisterType<TBattleField>.InjectMethod('AddFighter', ['knight']);

  GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
  GlobalContainer.RegisterType<TKnight>.Implements<IFighter>('knight').InjectConstructor(['sword']);

 

Some things to note:

  • We only changed the way things were registered.  We didn’t change the class structure or relationships at all.
  • We are now registering TBattlefield.  We need to do that for two reasons.  First, in our very simple example, it is the “root” of the application.  It is the place where everything starts in relation to our object graph.  To get an instance of TBattlefield, we make our one allowable call to ServiceLocator.  Second, we need to inject a method, as discussed next.
  • Into TBattleField we have injected a method, specifically the AddFighter method.  Here’s what the call to InjectMethod does -- it says “When the container creates an instance of TBattlefield, look up the AddFighter method and pass to it as its parameter an instance of the interface named ‘knight’”  Thus, when the container creates an instance of TBattleField for you, the AddFighter method will be automatically called, and a valid weapon will be passed to it.  There goes one call to the ServiceLocator
  • The second call to ServiceLocator is eliminated by the call to InjectConstructor.  This registration now means “When you ask for an IFighter, create an instance of TKnight, and when you do, pass the constructor an IWeapon from the registered type named ‘sword’”  Again, there goes the other call to ServiceLocator

Thus we’ve used the container to “wire up” all the dependencies and ensure that they are properly created before the main class or any other class is even asked for.  The call to GlobalContainer.Build in the DPR file will ensure this takes place. 

Finally, we run everything with the much simpler and cleaner:

 

procedure FightBattle;
var
  Battlefield: TBattleField;
begin
  Battlefield := ServiceLocator.GetService<TBattlefield>;
  try
    Battlefield.Battle;
  finally
    Battlefield.Free;
  end;
end;

 

And there’s our one call to ServiceLocator at the very root of our application (FightBattle gets called in the DPR file as this is a console application). 

You can do the same thing with constructors – you can call InjectConstructor, passing the names of registrations for each of the parameters in the constructor.  And if need be, for both InjectConstructor and InjectMethod, you can add in non-registered parameters such as integers and strings, etc.

Bottom line:  Use the injection methods and the container to connect up your classes and inject dependencies, not the ServiceLocator. 

And I haven’t even yet mentioned how you can replace the InjectXXXXXX calls with attributes. 

Okay, now I feel better since I agree with Mark Seemann over at http://blog.pleoh.dk.  Being in disagreement with a smart guy like that isn’t a comfortable place to be. 

THMTLWriter and XE4

By Nick at May 18, 2013 09:55
Filed Under: Delphi

I’m happy to say two things:

  • I’m still alive.  I can’t believe that it has been over two months since I posted. I have been working on my book, but it is sure slow going.  Writing is hard, as my wife says.
  • THTMLWriter works great with Delphi XE4. I’d be delighted to hear from you if you are using it.  And if you haven’t given Delphi XE4 a look, please do.  And use that link up there.  Please.

Flotsam and Jetsam #81

By Nick at March 01, 2013 16:36
Filed Under: Flotsam and Jetsam, Delphi
  • Embarcadero has revealed their plans for AnyDAC – and it is called FireDAC after all.  Marco blogged about it and has all the links.  Looks like all XE Enterprise developers get it as an upgrade/add-on, and Pro users can buy it for $399. 
  • I upgraded this site to BlogEngine.net 2.7.0.0.  It all seems to be well, but if you notice any glitches, broken links, missing graphics, or if one of your comments got lost in the shuffle, please let me know.
  • I can cross an item off my bucket list – I was honored by a mention in the Odd Lots column of the inestimable Jeff Duntemann.  I’ve been a fan for years, and was thrilled to get the mention. 
  • One final note:  There’s going to be less content here in the coming months. I’m going to put my patterns series on hold, and pretty much everything else I can spare, in order to work on my book.  I’ll be keeping up the F&J stuff – these are pretty painless – but the heavier content stuff won’t be happening as I work on my book.  Let me know if you want to help via codingindelphi@nickhodges.com and stay tuned for updates, etc.  And please feel free to let me know what you think over at the LeanPub site

Want to Help With My Book?

By Nick at February 26, 2013 22:08
Filed Under: Delphi

As you hopefully know, I’m working on a book.  I’m slowly but steadily making progress.  I’m at the point where I need some help.  I’ve gotten the first few chapters in a state that I feel ready to actually let someone else read them.

So if you are feeling generous, want to feel my undying gratitude, want to be mentioned in the Acknowledgements, and maybe even get a free copy, you can start technical editing!  If you are willing to provide some real and honest feedback on the first three chapters, knowing that things are still in a very early state, please email me at codingindelphi@nickhodges.com, and I can deliver the book to you in almost any form that you need. (Formatting, etc., is the least of my worries at this point……)

So, if you are interested, please let me know.  All help will be gratefully received. 

Delphi and the Factory Pattern: Factory Methods

By Nick at February 24, 2013 20:16
Filed Under: Delphi, Patterns

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 strongly encourage you to buy the book and read it for yourself.

Let me be clear – I’m not doing much more than reproducing the demos in the book.  My purpose is to make the book more approachable for Delphi developers.  The result isn’t always the perfect way to do the pattern since the samples from the book are designed to be as simple as possible to illustrate the point.  I’m very aware that there are better ways to implement the patterns than are shown here.

Introduction

In the first of three posts about the Factory Pattern, we looked at the “Simple Factory” pattern and how it can be used to sequester off your calls to create things.  HFDP didn’t rank the Simple Factory as a full-fledged pattern, but gave it an “Honorable Mention”.  Either way, it’s an effective technique to remove the notion of creating things from your worker classes.  Classes should only do one thing, and Factories do the one thing of creating dependencies so your other classes can do their one thing.

The reason that HFDP doesn’t make the simple factory a full fledged pattern is that they believe it isn’t robust enough to handle variations of the pattern.  It’s great if you have one pizza store.  However, if you want to open a new kind of pizza store – say a store in New York that serves New York-style pizza and then one in Chicago which will server Chicago-style pizza – then you are going to have some seriously ugly case or if statements. 

Branching out to New Pizza Styles

Okay, so the next step is to have different kinds of Pizza depending on where the store is (or, I suppose, the kind of clientele you want to attract, but we’ll just go with regional differences).  First we’ll need a pizza store that can adapt to the different kind of pizzas that the store will need to make. 

Thus we’ll add an abstract  method to TPizzaStore that will create the pizza for us in the descendent classes

  TPizzaStore = class
  protected
    function CreatePizza(aPizzaName: string): TPizza; virtual; abstract;
  public
    function OrderPizza(aPizzaName: string): TPizza;
  end;

The CreatePizza function is abstract, so descendent stores will have to implement it.  That way, each store will get to decide what kind of pizza it will make.  The OrderPizza method makes sure that all pizzas are handled in the same way, but the actual creation will be delegated to the descendent class via CreatePizza.

This is where the factory method part comes in – the TPizzaStore is an abstract class that let’s its descendant decide what kind of pizza it will create.  The call to OrderPizza becomes a “Factory Method”, determining which pizza will be created and thus how each pizza will be prepared.

Next, we’ll create a number of different pizzas that will be created by the specific factory methods.  We’ll create a cheese, pepperoni, clam, and veggie pizza for both the New York and Chicago styles.  (Creating at California-style set of pizzas is left as an exercise for the reader). 

TNewYorkCheesePizza = class(TPizza)
    procedure Prepare; override;
  end;

  TNewYorkPepperoniPizza = class(TNewYorkCheesePizza)
    procedure Prepare; override;
  end;

  TNewYorkClamPizza = class(TNewYorkCheesePizza)
    procedure Prepare; override;
  end;

  TNewYorkVeggiePizza = class(TNewYorkCheesePizza)
    procedure Prepare; override;
  end;

  TChicagoCheesePizza = class(TPizza)
    procedure Prepare; override;
    procedure Cut; override;
  end;

  TChicagoPepperoniPizza = class(TChicagoCheesePizza)
    procedure Prepare; override;
  end;

  TChicagoClamPizza = class(TChicagoCheesePizza)
    procedure Prepare; override;
  end;

  TChicagoVeggiePizza = class(TChicagoCheesePizza)
    procedure Prepare; override;
  end;

You can see the code on BitBucket for the specific implementations of the Pizza classes.  They override some of the methods to provide specific implementations for preparing the pizzas.  For instance, Chicago pizzas are cut in squares and use mozzarella cheese. 

Once the pizzas are available for creation, the specific pizza stores can be created. Below is the declaration and implementation of the TNewYorkPizzaStore.  (The TChicagoPizzaStore looks pretty much identical, except of course that it creates Chicago-style pizzas.)  It uses the OrderPizza method to decide what kind of pizza to create.  Inside OrderPizza is the call to CreatePizza which will get the appropriate pizza type.   Thus, it is a perfect example of a factory method which created things that you need. 

type
  TNewYorkPizzaStore = class(TPizzaStore)
  protected
    function CreatePizza(aPizzaName: string): TPizza; override;
  end; 

... 

function TNewYorkPizzaStore.CreatePizza(aPizzaName: string): TPizza;
begin
  if aPizzaName = 'cheese' then
  begin
    Result := TNewYorkCheesePizza.Create('New York Cheese Pizza');
  end else
  begin
    if aPizzaName = 'pepperoni' then
    begin
      Result := TNewYorkPepperoniPizza.Create('New York Pepperoni Pizza');
    end else
    begin
      if aPizzaName = 'clam' then
      begin
        Result := TNewYorkClamPizza.Create('New York Clam Pizza');
      end else
      begin
        if aPizzaName = 'veggie' then
        begin
          Result := TNewYorkVeggiePizza.Create('New York Veggie Pizza');
        end else
        begin
          raise Exception.Create(aPizzaName + ' is an unknown pizza');
        end;
      end;
    end;
  end;
end;

We still have a great big ugly if statement (There doesn’t seem to be a way to get around that, eh?) but the subclass is the class that decides what kind of pizza gets made.   The TPizzaStore class has no idea what kind of pizza is going to get made when the OrderPizza method is called, which in turn uses the CreatePizza method to return the proper kind of pizza.  That’s the Factory Method pattern to a ‘T’.

So to sum up:  we have an abstract pizza store class that defines how pizzas are ordered and created without knowing what kind of pizza will be created.  The concrete descendants determine what kind of pizzas get created via a factory method – in this case, CreatePizza.

Finally, we can actually create some pizzas using Factory Methods:

procedure MakeMethodPizzas;
var
  ChicagoPizzaStore: uFactoryMethodPizzaStore.TPizzaStore;
  NewYorkPizzaStore: uFactoryMethodPizzaStore.TPizzaStore;
  Pizza: uFactoryMethodPizzaStore.TPizza;
begin
   ChicagoPizzaStore := uFactoryMethodPizzaStore.TChicagoPizzaStore.Create;
   try
     Pizza := ChicagoPizzaStore.OrderPizza('cheese');
     Pizza.Free;
     WriteLn;
     Pizza := ChicagoPizzaStore.OrderPizza('pepperoni');
     Pizza.Free;
     WriteLn;
   finally
     ChicagoPizzaStore.Free;
   end;

   NewYorkPizzaStore := uFactoryMethodPizzaStore.TNewYorkPizzaStore.Create;
   try
     Pizza := NewYorkPizzaStore.OrderPizza('cheese');
     Pizza.Free;
     WriteLn;
     Pizza := NewYorkPizzaStore.OrderPizza('clam');
     Pizza.Free;
     WriteLn;
   finally
     NewYorkPizzaStore.Free;
   end;
end;

 

The pizza store types are prefaced with their unit identifiers to keep them distinct from the pizza class from the abstract factory demo that we’ll see in the next installment of the Factory Pattern demos.

That’s the Factory Method Pattern – you create an abstract class and then descend from it to implement a method for creating the right class.

Next time, we’ll look at how you can create an entirely separate interface for completely abstracting the notion of creating things.

Fun Code of the Week #7

By Nick at February 24, 2013 09:08
Filed Under: Fun Code, Delphi

It’s all a big circle.

First, I posted a fun little way to handle the cursor in this Fun Code of the Week.

The first comment on that post was from my friend Tapper who said “What, no interface?”

Then, I post this about hints revealing errors with cursor handling as part of the demo.

And from that, we get a comment by Leif that I’m making Fun Code of the Week

So Tapper is happy, and we all have about three ways to handle the cursor. 

Wins for everyone!

 

unit CursorHandler;

interface

uses
      Controls
    ;

type
  ICursor = interface(IInterface)
  end;

function AutoCursor(const aCursor: TCursor): ICursor;

implementation

uses
  Forms;

type
  TAutoCursor = class(TInterfacedObject, ICursor)
  private
    FCursor: TCursor;
  public
    constructor Create(const aCursor: TCursor);
    destructor Destroy; override;
  end;

function AutoCursor(const aCursor: TCursor): ICursor;
begin
  Result := TAutoCursor.Create(aCursor);
end;

constructor TAutoCursor.Create(const aCursor: TCursor);
begin
  inherited Create;
  FCursor := Screen.Cursor;
  Screen.Cursor := aCursor;
end;

destructor TAutoCursor.Destroy;
begin
  Screen.Cursor := FCursor;
  inherited;
end;

end.

My Book

A Pithy Quote for You

"The hardest thing in the world to understand is the income tax."    –  Albert Einstein

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.

Month List