Wednesday, July 30, 2008

The LinFu Reimplementation Plan, and Dogfooding

Before I hit the ground coding, let's go over some of the features that were in LinFu v1.0 that will also be in 2.0:
  1. Dynamic Proxies
  2. Late Binding / Multiple Dispatch
  3. Duck Typing
  4. Mixins
  5. Universal Event Handling
  6. Closures with Lambda Arguments
  7. Design By Contract
  8. AOP (static and dynamic weaving)
  9. Inversion of Control / Dependency Injection
  10. Adaptive Object Models
  11. A MyXaml Engine Clone
Aside from the fact that v1.0 has a fairly hefty feature list, one thing that I've noticed with the source is that despite those features, LinFu itself doesn't really use its own IoC or DbC facilities to improve the quality of its own code, and that's a wasted opportunity.

With that in mind, I've decided to implement the following features first:
  • Inversion of Control / Dependency Injection
  • Dynamic Proxies
  • Design by Contract
  • Static AOP Weaving
Building an IoC/DI container will help enforce a separation of concerns, and using Design by Contract in tandem with TDD will eliminate over 90% of the bugs in the code. The reason why I'm also implementing the static AOP weaving and dynamic proxy generator first is that there has to be a way to transparently inject those contracts into a service instance using a dynamic proxy without having to clutter the original source code. In addition, using the static AOP weaving in a debug build will allow me to dynamically inject diagnostic code without affecting the actual release build.

As for LinFu's Design by Contract v3.0, my goal is to make it injection-agnostic. That means that the library itself should be completely unaware of how it's actually being injected into a service instance. It will allow you to inject contracts using a 3rd-party dynamic proxy generator (such as Castle), and most importantly, it should make no distinction between LinFu's static AOP injection and its own proxy generator.

Probably the most striking difference that you'll see between v1 and v2 is that LinFu will no longer be split into multiple projects (aside from PostWeaver.exe, and the MSBuild task for LinFu.AOP). There might be some who might say that clumping all of LinFu into one DLL violates the principle of Separation of Concerns, but in practice, it will save you an untold amount of headaches when managing your project dependencies.

I realize that rebuilding LinFu is a very tall order, and I'm putting my heart and soul into this one to make sure that it's the best code that I'll ever write. This is going to take some time to redo, and I'll keep posting more and more updates on my blog as time progresses.

Tuesday, July 29, 2008

Behavior-Driven Development to the Rescue?

I've been trying to wrap my head around how I can increase LinFu's test coverage rate for over a week now, and I have to admit that doing DDT testing (aka TDD in reverse, or post-hoc unit testing) is much more difficult than its TDD counterpart.

In contrast, TDD seems to apply a bottom-up approach to ensure that each component is functioning, and in LinFu's case, I'm going to need a top-down testing approach to ensure that all of LinFu's features work as advertised. My intent is to write each test as a specification for LinFu's behavior, and each one of these tests will ensure that LinFu behaves according to its specification.

It's by no means perfect, but it's the only practical solution that I can apply to the existing code base without having to rewrite it. At best, it seems like an ugly hack since I'll be effectively doing black box testing against LinFu instead of getting the 100% test coverage.

The other alternative, of course, is that I can do a complete rewrite of LinFu (presumably version 2.0) from scratch. (It's not a pretty option, but then again, it's no better than having to do post-hoc unit testing).

So here is my question for the developer community at large: Which option should I take, and why? If I do LinFu v2.0 with a 100% test coverage rate, will that up the adoption rate, or will LinFu v1.0 with specification tests added be sufficient enough to fix the test coverage problems?

Wednesday, July 23, 2008

LinFu, and Biting the Testing Bullet.

Ok, I just have to admit it. LinFu still needs a lot more work. The test coverage is still 'awefully low', and despite the fact that I've kept my code clean and simple, it still doesn't take away from the fact that other programmers rely on automated unit tests to verify that your code works as advertised. I think Jeremy Miller said it best when he sent me this email:

I'm giving you an A+ for the outright coolness of LinFu and the Comp Sci nature of things, but I'm questioning the software engineering. To put it another way, I think you'll get far more adoption of LinFu if you have a better story to tell about the testing. If you retrofit a battery of automated tests to at least cover the dynamic proxy and maybe the AOP, I'd be very interested in using LinFu inside my own StructureMap project.

Jeremy definitely has a point there, and in some ways, it's a bitter pill for me to swallow. The bottom line is that LinFu won't get widespread adoption unless I can increase its the test coverage rate. The irony here is that since I have a low test coverage rate from the start, I'll be subjecting myself to some of the same ills that I woefully complained about in other developers.

With that in mind, I've decided to suspend all new development work on LinFu until I can resolve the test coverage issue. I will find a way to get to 100% unit test coverage, even if it means that I'll have to rewrite everything from scratch.

LinFu is officially on lockdown mode, and I've got some major cleaning up to do.

Ratings by outbrain