Amazon.com Widgets July 2011

Flotsam and Jetsam #40

By Nick at July 27, 2011 16:50
Filed Under: Delphi, Flotsam and Jetsam, Software Development, TechBiz

Getting Giddy #4 Fixed

By Nick at July 10, 2011 20:52
Filed Under: Delphi, General, Software Development, Unit Testing

Okay, so I was getting all these emails about the fourth article in my “Getting Giddy” series of articles.  You guys kept saying it was missing and I kept saying “Hey, it’s right here!”.  And then finally I noticed – #4 and #5 were identical.  I must have done something stupid somewhere.  Well, I was able to track down the original article on my hard drive and restore it.  So now, the fourth article is as it should be, and all seems well with the universe.

Sorry for the confusion, and I appreciate the interest that these articles have generated.

Getting Giddy with Dependency Injection and Delphi Spring #4 – Dependency Injection Basics

By Nick at July 10, 2011 20:48
Filed Under:

So now after the first three parts, you are probably wondering – What the heck is he getting at?  Wasn’t he going to talk about dependency injection?  What the heck is this dependency injection anyway?

Okay, so let’s get down to more practical matters.  Earlier I recommended the Martin Fowler article that (I believe) actually coined the term “Dependency Injection”, but that article is a bit wonky.  I’m going to try to be a bit more practical and “examply” here, and of course, I’ll be showing everything in Delphi.  We’ve talked about the Law of Demeter and why writing testable code is a good idea, so now we’ll get down to it and show how we might actually go about doing what I’ve been talking about.

So, Dependency Injection.  Well, Dependency Injection (I’ll call it ‘DI’ from now on) is really just a way of providing functionality to a given class without creating a specific dependency on that class.  That is, the dependency is “injected” – provided -- for you.  There are a number of  ways to do this from the simple provision of a class to the use a complex framework and  attributes to define dependency instances.  By “specific” I mean that DI will allow you have control over how dependencies are provided.  For instance, you may want to control the injection of  dependency depending on whether you want to run things “for real” in production or what to run them as unit tests.

So by way of getting started, I’m going to define two rules (in addition to “Follow the Law of Demeter” and “Write Testable Code” that is…) that you should follow to make the use of DI easier and simpler. 

Rule #1:  Always code against interfaces

This might seem a bit weird, but I think it is a critical  practice to follow.  Interfaces define a given set of functionality, and that, really, is all you need to provide, right?  A given set of functionality?  A side-rule to this is “Never put a class in the interface section of a unit”.  Now that may seem a bit radical, but if you do this, you are pretty much guaranteed that you’ll follow the Law of Demeter.  A class in the implementation section of a Delphi unit cannot be coupled to outside of that unit.  It cannot be used or abused anywhere. 

Consider the following code: 

unit uNormalMathService;

interface

type
  IMathService = interface
    ['{BFC7867C-6098-4744-9774-35E0A8FE1A1D}']
    function Add(a, b: integer): integer;
    function Multiply(a, b: integer): integer;
  end;

function MathService: IMathService;

implementation

type

  TMathService = class(TInterfacedObject, IMathService)
    function Add(a, b: integer): integer;
    function Multiply(a, b: integer): integer;
  end;

{ TAdditionServiceImplemenation }

function TMathService.Add(a, b: integer): integer;
begin
  Result := a + b;
end;

function TMathService.Multiply(a, b: integer): integer;
begin
  Result := a * b;
end;

function MathService: IMathService;
begin
  Result := TMathService.Create;
end;

end.

This code provides a clearly defined set of functionality, implements that functionality, and makes that functionality available to anyone who wants to use it.  It does all of this without exposing any class at all to anyone outside of the unit.  All you get is an interface and a means of getting an interface via a function call.  (It’s simpler than you’d probably like it all to work, but it’s illustrative of the point….)  You can’t do anything other than use TMathService via the IMathService interface. You can’t abuse and otherwise mess around with TMathService because it is completely hidden from everyone. 

IMathService is easy to test, too.  You can grab an interface, and run tests on it to your hearts content.  And as we know, “easy to test” is a mantra akin to “look both ways before crossing the street” or “Don’t cross the streams”.

And in fact, as we move forward, a really cool part here is that you can provide different implementations of the IMathService interface if need be.  That can provide all kinds of flexibility in the areas of testing and production.  For instance,  if you somehow come up with some better way of adding and multiplying numbers, you can can change to the new way without having to worry about breaking anything at all.  Since it’s easy to test a specific interface implementation, you’ll have a complete suite of unit tests, and can change the implementation with confidence. 

Rule #2:  Keep Constructors Simple

Here’s a good rule of thumb for our second rule:  Don’t create anything in your constructor.  At all.  Ever.  Your constructors should do little else than assign values to field variables.  If your class needs something, it should ask for it.  To start, we’ll do the “asking” via parameters in the constructor.

Another thing to consider is that you should never have conditional code in your constructor.  If you are feeling the need to put an if statement in your constructor, you almost certainly need to break the given class up into two sibling classes with a common descendent.

Consider the following code: 

unit DIBasics;

interface

type

  TPizza = class

  end;

  TPizzaOven = class
    procedure Bake(aPizza: TPizza);
  end;

  TPizzaMaker = class
  private
    FPizza: TPizza;
    FPizzaOven: TPizzaOven;
  public
    constructor Create;
    destructor Destroy; override;
  end;

implementation

{ TPizzaMaker }

constructor TPizzaMaker.Create;
begin
  FPizza := TPizza.Create;
  FPizzaOven := TPizzaOven.Create;
end;

destructor TPizzaMaker.Destroy;
begin
  FPizza.Free;
  FPizzaOven.Free;
  inherited;
end;

{ TPizzaOven }

procedure TPizzaOven.Bake(aPizza: TPizza);
begin
  // bake the pizza
end;

end.


This code has all sorts of problems, no?  Right away, you can see all kinds of coupling.  The TPizzaOven class is directly dependent on TPizza.  The TPizzaMaker class depends directly on TPizza and TPizzaOven.  What if you want to bake a TPepperoniPizza? 

Basically this code defies practically everything that I’ve been telling you not to do. 

Okay, so, let’s apply the most basic form of DI on this code.  I’m not sure if it has a name, but I’ll call it “Dependency Injection via Constructor Parameters”  (as opposed to “Constructor Injection” which is, as we’ll see, something entirely different):

unit DILittleBetter;

interface

type

  TPizza = class

  end;

  TPizzaOven = class
  private
    FPizza: TPizza;
  public
    constructor Create(aPizza: TPizza);
    procedure Bake;
  end;

  TPizzaMaker = class
  private
    FPizzaOven: TPizzaOven;
  public
    constructor Create(aPizzaOven: TPizzaOven);
  end;

implementation

{ TPizzaOven }

procedure TPizzaOven.Bake;
begin
  // bake the pizza
end;

constructor TPizzaOven.Create(aPizza: TPizza);
begin
  FPizza := aPizza;
end;

{ TPizzaMaker }

constructor TPizzaMaker.Create(aPizzaOven: TPizzaOven);
begin
  FPizzaOven := aPizzaOven;
end;


end.

Here, the thing we’ve done to reduce the coupling and the dependency is to have the classes not create their own instances of what they need, but instead, to “ask” for those instances via the constructor.  The TPizzaOven and TPizzaMaker classes get their dependencies provided to them via parameters on their constructors.  The constructors merely assign the passed in references to local variables.  This way, the “link” between the classes is much looser and the flexibility of the whole system is increased while making the classes less coupled together. 

And here’s another reason to use interfaces – the above code doesn’t really cleanly answer the question of the lifetime of the classes passed to the constructors.  Who is in charge of freeing the classes – the caller or the class itself?  The TPizzaMaker and TPizzaOven classes assume that the classes passed to them will be freed elsewhere but there may be occasions when that isn’t the pattern you want to follow .  If you use interfaces for everything, you don’t’ have to worry about the lifetime of your objects – Delphi’s reference counted interfaces will be “garbage collected” for you (for lack of a better term). 

So at its base, DI is the notion that a class should ask for the things it needs and not create those things itself.  There are any number of ways to ask for a given need.  “Dependency Injection via Constructor Parameter” is a very nice way to inject dependencies into a class.  It can get a little messy though, because in order to create a class, you often have to create multiple classes to pass as parameters. 

So, what if you had a system that allowed you to inject dependencies into your classes without even having to really create the classes in the first place?  What if instances of your dependencies could just auto-magically appear out of nowhere without you having to really do anything much at all?

Well, that is what DI frameworks like Spring do, and we’ll take a look at that in our next installment. 

Flotsam and Jetsam #39

By Nick at July 10, 2011 18:25
Filed Under: Flotsam and Jetsam, Delphi

Flotsam and Jetsam #38

By Nick at July 07, 2011 09:26
Filed Under: Delphi, Flotsam and Jetsam, Software Development

A Bunch of Stuff I’d Like to See Embarcadero Do

By Nick at July 05, 2011 22:22
Filed Under: Delphi, Tech Stuff, TechBiz

There are a bunch of things that I’d like to see Embarcadero do.  I’ve listed and discussed some of them below.  I’ll probably think of more later.  Winking smile  They are in no particular order, and they are not grouped in any particular way.  They are a bit random, and range from business decisions to minor technological decisions. Where it makes sense, I’ve linked the titles to the entries on http://delphi.uservoice.com/ so that you can vote for the items if you see fit.

I’d like to see Embarcadero:

  1. Provide an Enterprise-level MVC web framework for Delphi.  This almost seems like a no brainer to me. Ruby on Rails has had a profound impact on web development and development in general.   In the .Net world, MVC has become the leading ASP.NET development method,winning over hearts and minds from WinForms.  The general idea of MVC is becoming the norm for much of the development world – separate those concerns!. Delphi’s new RTTI capabilities would actually make this kind of framework very, very possible and very, very cool.  And Delphi already has a very powerful and capable web infrastructure to build on:  good, old, and venerable WebBroker.  There are even existing frameworks out there that could be leveraged, including the G Framework.   There is a business opportunity here for Embarcadero, if not for an enterprising third-party Delphi developer.  A native, ISAPI based MVC framework in Delphi?  That would be very, very sweet.
  2. Stop trying to do other stuff and invest in Delphi.  This one has been one of my huge frustrations over the years.  Delphi is a profitable product, but no matter who owns or runs the show,  the profits always seem to get skimmed off to fund other “next big thing” projects of, well, questionable benefit at best.   Remember “SDO” taking the market by storm? Yeah, me neither. AppWave seems to be interesting and have a lot going for it, but I personally would rather have seen that effort invested back into Delphi.  I hate to think about where Delphi might be today if it hadn’t been used to fund other projects and instead been allowed to use it’s profits for it’s own development.  Delphi could use a year or two of un-distracted attention from its owner. 
  3. Create a Javascript/HTML development tool.  I’ve always said “As assembler is to the Intel chip, so Javascript is to the browser”.  James Governor has it right:  “Learning Javascript used to mean you weren't a "serious software developer". Today, not learning Javascript means the same thing.”  A powerful, feature rich RAD development tool for Javascript and JQuery would be really cool and a great new product for Embarcadero.  Maybe RADPHP could be steered in that direction?
  4. Make Dependency Injection part of the RTL: If you haven’t figured it out yet, I’m a big believer in Dependency Injection.  So much so, that I think that if you aren’t doing Dependency Injection, then you are doing it wrong.  Incorporating a DI Container into the Delphi RTL would be very cool.  Again, Generics, anonymous methods, and the new RTTI makes is very easy and powerful, and there are open source projects to leverage and build on (like my favorite, Delphi Spring).
  5. Do one thing at a time and do it really well:  This is the one that I wish they would do the most:  Take the product forward one step at a time. For instance, the next release should have as it’s main focus 64-bit Delphi and only 64-bit Delphi. That’s it.  Other improvements can be made, of course, but clearly that should be the “big one”, and it should be the only “big one”.  Don’t try to do two or three “big ones” in a single release. Make each release focused on a big, single step forward, executed thoroughly and solidly.  The product will be fine as long as it shows steady, sustained improvement.  Many large improvements executed all at once is not what the market wants.  Focus and deliberately move forward.

That’s all for now – I’ll probably have more as I think of them, but that ought to be food for thought for while

Changes to the Website

By Nick at July 01, 2011 19:08
Filed Under: General

As you’ve probably noticed, there have been some changes to my website here.  I thought I’d list what I did:

  • I updated the engine to BlogEngine.Net 2.5.
  • I updated the theme as well.  I wanted one where the main content isn’t fixed in width. I’ve been posting a lot of code samples, and having a fixed with for those wasn’t working like I wanted.  I also thought it was time for a “fresh look”.  I’ll be tweaking the theme going forward – I’m still not happy with all the font sizes.
  • I added a Google Plus One button to each post after the buttons from AddThis. I also made those buttons a bit more prominent.  Feel free to click those buttons if you like what you see.  Winking smile 

Of course, if you notice any problems, issues, etc., or have any feedback and/or suggestions, please let me know.

My Book

A Pithy Quote for You

"There are no such things as limits to growth, because there are no limits to the human capacity for intelligence, imagination, and wonder"    –  Ronald Reagan

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