Thursday, December 19, 2013

Book Review: "Coding in Delphi" : A new Delphi book by Nick Hodges

Right now you can only get it by buying Delphi XE5.  I just finished reading it, and I love it.  I think that the title needs to be understood with the word "Modern" put in there somewhere. Maybe "Coding in a Modern Delphi Style" would fit the content well.  The title is fine, but I'm just putting that out there so you know what you're in for.

Did you want to know more about the proper use of Generics, not just the consumption of a Generic type (making containers using TList<TMyObject> ) but also enough to start really building your own Generics?  Do you want to learn how to dive into Spring4D (Spring for Delphi) and use its powerful capabilities?  Do you want to learn to use fakes (stubs and mocks) to isolate classes so they can be truly unit tested? Do you understand the real difference between unit testing and integration?  If you're not using isolation frameworks, or you don't know how to use them, or isolate your classes, is it possible that there's a whole new and better  level of test coverage?

Do you feel that you were late to the party, and nobody ever explained all the things that the cool up to speed delphi developers know?   This book is conversational, friendly, approachable,  code-centered, and although I already understand 90% of what is in the book, I still found there were some parts that really made my head bulge a little.

The book focuses on the raw coding aspects, and low level coding concerns, not on high level issues like user interface, or even architectural concerns like MVC.   The well known and beloved core Object-Oriented principles in the S.O.L.I.D. family, as preached by Uncle Bob Martin, are mentioned and given brief homage, but not expanded upon.  This is well and good, or Nick would still be writing this book and it would be eight times its current length.

Having finished reading the book, I'm going to go download all the add-ons and frameworks and libraries that Nick has gone over, and spend some time playing with them, and then I'll go read the book again.   I think that if you try to absorb everything in the book at once, you might get a bit of a headache. Instead I took it in over a couple days, let it wash over me and then I'll go back over it again in more detail.

I believe so strongly in the KISS and YAGNI principles, that I still don't think I'll be using all the shiny things that Nick talks about in this book, unless I can clearly see how using them benefits both the developers and the users of the code.  But I'm so clearly sold on the benefits of isolation, and testability, and design for quality and testability, that you don't have to sell me any further. It's just a matter of using these technologies in a way that can be done without substantially degrading debug capabilities.  (That is the secret down side of interfaces, and isolation, and dependency injection.  Your code can turn into a mysterious pile of mysterious semi-readable angle-bracket soup.)  

I am hopeful that there is a way to pacify both the desire in me to build testable, quality systems, and the desire to build readable simple systems that don't go down the Hammer-Factory-Factory road to hell.

If you want a copy, go buy XE5, or wait until some time next year when the book will have a wider release.  It's great though. You really should get it.  Nick joins my other favorite Delphi authors, like Marco Cantu, Bob Swart, Xavier Pacheco, and Ray Konopka on the virtual Delphi book authors shelf in my coding book collection, and it's a fine addition to the canon of Delphi books.

  

14 comments:

  1. I agree with your concerns of having a hard time debugging interfaced based code (or using "Find declaration just to end in the interface declaration without seeing any code unless you step into it while debugging).

    However if you are doing proper unit/integration testing this will reduce the amount of debugging through the real application and your scope is much smaller with less of the problems mentioned before.

    ReplyDelete
  2. It is interesting that we trade one problem for another so often. Debugging is too hard so we need more unit tests. Unit testing needs interfaces and magic action at a distance (Dependency Injection container), which makes debugging harder, and gives bugs a new place to hide.

    ReplyDelete
    Replies
    1. "Debugging is too hard so we need more unit tests"

      No, you should have unit tests regardless how difficult or time consuming debugging is.

      "Unit testing needs interfaces and magic action at a distance (Dependency Injection container)"

      If your unit tests need or contain a DI container you are doing it wrong. They should test single components and setting up dependencies should be done by hand in a unit test. If you want to test the whole system or parts of it (including the DI container) you are doing integration testing.

      Delete
    2. If doing unit testing requires isolation, and isolation requires dependency injection, and dependency injection requires interfaces, and a dependency injection container, then you have the problem. You have not addressed my concern. Saying you're not doing unit testing if you don't isolate is not disagreeing with me. Saying that unit testing can be done without isolation is disagreeing with me. Are you disagreeing? Because it seems to me you are not.

      Delete
    3. The whole practice of unit testing in the Delphi context begs for a book. Stefan? Warren? ;)

      Delete
    4. If that is your opinion then you have the problem, Warren.

      Unit testing does not require isolaton - have fun writing untestable (or hardly testable or only testable if including everything and the kitchensink) code - I suggest reading and watching Misko Hevery's clips and guides about that.

      I am not sure if your understanding of dependency injection is the same as mine. Since dependency injection just means passing in something that is needed - I guess you have called a method that takes a parameter more than one time in your life. Because this is dependency injection. This is basically a tool to decouple things instead of stuffing everything into one piece.

      Also dependency injection does not require interfaces - it might require abstractions which is what interfaces are. Getting the reference counting for free can be a benefit when having object graphs where you don't want to keep track of everything manually.

      I can say it again. You don't need a DI container to do dependency injection and actually I recommend not using one until you fully grasp what DI is all about.

      I am surprised because I thought you watched Robert C. Martins presentation that you linked the other day because at some point he was pointing out the benefits of clean code and unit tests.

      Delete
    5. Wow, yes, I did watch them. I do understand the benefits and I want them as much as Bob does, and presumably, as much as you do. What I do not do is feign that everything is going well when it isn't. It isn't going well. I'm looking for solutions to the additional complexity that isolation brings. I have found that indeed, either interfaces or pure virtual base classes that are defined in their own units are necessary. Once you have pure virtual base classes, the distinction then comes down to the classic Delphi manual lifetime management strategy versus the Interface lifetime management strategy decision.

      I have not only watched those videos, I read Bob's book on Clean Code, and I agree with it. However, I'm not willing to gloss over the problems I'm having getting there. This is more a cry for help than an attack on TDD or Unit Testing.

      W

      Delete
    6. Well, now we are talking. I agree with you. Looking back at the history of Delphi mostly being RAD and EMBT supporting that (see Livebindings f.i.) it is understandable. The IDE itself does not actively support a way of coding that does not lead to the "big ball of mud". If that was the case it would make peoples live easier - I am not talking about writing some small tool application where nobody cares about proper design patters use.

      But once you start working with a team on a big application you should start thinking about these things. And I think most of us have worked on such a project in the past where that was not the case.

      Nicks book certainly raised the awareness for these things and now we have to see where and how we can make use of that and how to improve the tools to support this mindset.

      Delete
  3. Unit testing also adds code documentation, allows automated testing on build servers, and gives new hires something to read while you're finding work for them.

    ReplyDelete
  4. @Stamp: Good points. I love unit testing. However I am still trying to figure out how to apply it to legacy code-bases without changes that themselves will break the code and make it unable to ship. This is what we in the biz call a "hard problem".

    ReplyDelete
    Replies
    1. Did you read the book "Working Effectively with Legacy Code" yet?

      Delete
  5. Stefan : Yes I read it, but one concern that it doesn't cover is the special cases that I find in the GUI ball of mud. I have found the general "under test" condition to be easiest to achieve if I fall back to Integration Testing, and use simple small test databases to achieve fast-as-possible integration testing, and use that to drive my "under test" scenarios, even though it's not a single-class test.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Thanks for your review! Is this book also worth to buy for Free Pascal users? How big is the part of Delphi-only frameworks

    ReplyDelete