The evolution of design, and the continued search for "The Way"

I'm currently finding myself in the midst of an evolutionary change.  And I'm not talking about my super-human mutant powers, I'm talking about the way I'm thinking about solving a specific set of problems.

Let's start with a sample....Lets take something like processing credit-cards as a benign and IP free place to start.  As a subject that I really have no practical experience with, it seems like an appropriate choice.  I'm going to assume that there are different rules for doing checksum validation on credit card numbers, depending on what the card is (Mastercard/Visa/Discover/etc). Now, here is evolutionary step 1: Use a basic case statement to process the various cards.  Here is what something like that would look like:

switch(CardType)
{
    case CardType.MasterCard:
        CardValidators.MasterCardValidator(card.CardNumber);
        break;
    case CardType.Visa:
        CardValidators.VisaValidator(card.CardNumber);
        break;
    case CardType.Discover:
        CardValidators.DiscoverValidator(card.CardNumber);
        break;
}

 

This looks pretty straight-forward, and as it stands it isn't too bad from a maintainability stand point.  But what happens when there are many different types of cards?  An then what happens when you find a large amount of duplication between the validation functions?

Well, any student of GoF should be able to tell you that a Chain Of Responsibility pattern looks like a perfect fit for this sort of scenario.  So, evolutionary step 2: Create separate classes to handle the different types of validation, and configure them in a Chain of Responsibility pattern where each instance decides for itself whether it can process the input.

Here is a quick and dirty look at what something like that would look like:
ClassDiagram1

 

The two most interesting things here are the GetValidator() method in the AbstractCardValidator, and the individual CanValidate() methods in the concrete implementations.  What this does is it allows each class to decide for itself how it is going to determine whether or not it can be used as a validator for a specific card (thats the CanValidate() part), and also provides a single point which the consumer of the API can use to get the validator for the card instance they have.  You would probably want to build and Abstract Factory around this, which would instantiate all of the ICardValidator classes, and then run the GetValidator() method to get the correct one.

Now we are at a point where things are looking pretty good; we've got the ability to do some fairly complex logic to make the decision about which validator to use, and we have a way to simply ask for one, and the correct one appears.  Pretty cool.

This is actually the place where I have found myself in the not to distant past.  I have previously been perfectly content with this arrangement, and been fairly happy with the separation of concerns among the classes...I mean, after all, who better to decide whether or not a specific class should be used to validate a card than the class itself.  So what is the issue?  Well, recently I have become aware of two problems with this arrangement: Tight Coupling, and a violation of the Single Responsibility Principle.  Let's start with the first:

Tight Coupling
The credit card example may be a bit contrived when it comes to this issue, but bear with me.  Overall, the issue is that specific instances of ICardValidtor objects are being created and handed around.  The use of an interface and an Abstract Factory pattern would actually help the situation out some, but effectively all it does is move the coupling from the consuming class to the Factory (okay, it also consolidates coupling to a single class, which makes maintenance a lot easier).  As I said, contained, but still there.  It would be nice if the factory didn't need any knowledge of what concrete instances of ICardValidator were out there.  Before we tackle that, though, lets also look at the second issue:

Violation of the "Single Responsibility Principle"
The SRP states that a class should have one, and only one, thing it is responsible for.  Sounds pretty easy doesn't it?  The problem is that this can be difficult to obtain without a fair amount of discipline.  The violation of SRP which I'm seeing is that the ICardValidator is responsible for both validating a credit card and determining which validator is appropriate.  But wait!  Didn't I just say that moving this check into the ICardValidator instance was a "Good Thing"?  Well, lets go as far as saying it is better than the previous method, but still not perfect.  Applying the SRP would move the task of selecting a validator from the ICardValidator instance, and put it on it's own somewhere.  So, thusly we come to our:

Inversion Of Control Container.
That's right, we are now going to get crazy and move the responsibility of creating these instances to another component all together.  The nice thing about this is that it allows us to move all of the knowledge about dependencies off somewhere else.  How does this apply to this example?  Well, lets assume we have an object of type Card which requires as a dependency an instance of an ICardValidator.  We'll also assume that Card is subclassed based on the type of credit card.  It now becomes trivial to configure our IoC container to supply a specific implementation (read sub-type) of ICardValidator for each implementation (again, read sub-type) of Card.  Now, when you want a Card instance, you ask the IoC container for one, and depending on what type of card it is, you will get the appropriate ICardValidator as well.

What's the catch?  Well there is some additional complexity which will show up somewhere in the application due to the IoC, but typically IoC configuration can be delegated down to the configuration file level, so even then the ugliness is pushed away to it's own dark corner.

But wait!  Why should we have different instances of Card?  What if the Card class is just a container for the card data?  Well, our Ioc still gives us some advantages.  If we look back at our first example with the switch statement, we've got a nice CardType enum, which could be a property of our Card class.  Using an IoC container like the one provided by the Castle project, you have the ability to configure a key string for your instances.  This would make it trivial to map the enum choices to specific keys within the container, which the Card class would use to get an ICardValidator instance.  This would also make it possible to make the validators slightly more advanced by adding something like a Decorator pattern, in which specific aspects of the validation could be factored into separate classes, and then "stacked" to produce the final validation logic (This is the same concept used by the Stream classes in .Net and Java.  You can modify the behavior of a stream by passing it to the constructor of a stream with different behavior).

It is definatly worth mentioning that there is a sudden appearance of tight coupling to the IoC container itself from our consuming classes.  You probably want to try to abstract away the fact that the IoC container exists from the majority of the application.  Factory classes go a fair ways in making this happen, but another good idea is to introduce a single service to do type resolution.  The Factory classes can then ask this service for the object they want, and they never need to know the IoC container is there.  This approach also gives you the ability to create some objects using IoC and others in another (more traditional) way.

So is this it?  Have I finally found the answer I've been looking for?  It's hard to say right now.  For the time being this is a decent way to handle things, provided the complexity of the underlying system, and the need for loose-coupling are both high enough to justify the additional complexity of the IoC.  But who knows, in another couple months I may find something new, or even something old, which seems better, cleaner, simpler.  That, after all, is my final goal....And I need to remind myself of that regularly, lest I become complacent.

Tags:

Protect Yourself - Use TDD

So I had this analogy pop into my head a while back and I've been sitting on it because, quite frankly, I was almost embarrassed to have thought of it.  I finally decided that I might as well post it since no one is going to read this anyway, so here goes:

Writing software without TDD is like having unprotected sex.  Its extremely irresponsible in this day and age when everyone is supposed to know better, but it still happens a lot.  Sure, it feels better, and let's face it in the heat of the moment you really don't want

 to take the time to make sure you've taken all of the right precautions...you might loose your edge.  The problem is if we don't do it we have that lingering fear in the back of our minds, that "What if?" that keeps popping up at the worst moments.  Most of the time its okay, and everything is fine, but it only takes one time for things to go wrong to make you regret your decisions.

So come on folks, we all know what we should be doing, so no more making excuses.  After a while you get used to it, and you find that the peace of mind it gives you far outweighs the momentary delights of living on the wild side.

Tags:

More On Testing and "Friend" Assemblies

So if you recall from some of my earlier posts, I've talked about the concept of the "Friend" class in C++ and how it could apply to TDD within .Net.  Well, today, with the help of Roy Osherove, I just stumbled upon the InternalsVisibleToAttribute within .Net 2.0.  This allows you to specify within one assembly, another assembly that should have access to the internal members of your assembly.  This is genius, and goes a long way towards allowing you to keep your code encapsulated, while still being testable.  If we could just get them to go one step farther, and allow for access to private and protected members as well, life would be good, and there would be no more of this OOD vs TOOD junk.

The other interesting thing about this is that it could allow you to give a separate utility...say the Castle Microkernel, access to internal class constructors, and thus enforce creation of your objects through the Kernel from outside assemblies.  This is actually a feature I am desperately wanting in my current project,  but sadly, I am limited to .Net 1.1, so I can't quite get there.

Here is a quick look at how this works.  Here is a very unrealistic class in an assembly that I want to test:

class TestClass
{
    internal TestClass()
    {}

    private bool PrivateMethod()
    {
        return false;
    }

    internal bool SomeMethod()
    {
        return true;
    }

    public string PublicMethod()
    {
        return "You can see me";
    }
}

Now, I add the following to the AssemblyInfo.cs file:

[assembly: InternalsVisibleTo("TestAssembly")]

And here is what Intellisense looks like in my test class

Not bad.  Overall I would say this is defiantly a good feature to have in your toolbox.  Internals are not perfect, but they are much more versatile than a lot of folks give them credit for.  Now if only I could get something like this in .Net 1.1

Tags:

I love Mock Objects, but am I a "Mockist"?

I have officially crossed over....I am now using Mock Objects in my tests and loving it.  After much humming and hawing, and trying to figure out how to write truly effective tests, I decided to give it a go, and so grabbed a copy of Rhino Mocks and started the grueling task of converting some data access code so that I no longer needed a database to run the tests.  It took a little bit to get my mind around the new way of thinking, but I have to say it worked great.  I'm now able to test my data access routines with complete success, and about a 95% code coverage rate.  This is all on top of the fact that I'm using Enterprise Library (for 1.1) for data access and exception handling.

Now, there is a very interesting article from Martin Fowler which is called simply "Mocks aren't Stubs".  In this article he is discussing two approaches for dealing with the sort of problem that I had with my data access code.  One is to create object stubs within your tests that you can use to feed known values back to your tests.  This is not at all a bad approach, and I am using it in some cases in conjunction with my mock objects.  The other approach is to use Mock Objects for all of the tricky stuff.  He observed an interesting dichotomy between the sort of TDD folks who follow each approach:  The folks that use stubs tend to be very results oriented in their testing...That is they are verifying the values of various object after performing an action using the test frameworks Assert calls.  This, I think, is most in line with the way TDD is supposed to work.  For the Mock Object folks, though, another thing starts to happen.  These test gain the ability to verify that specific methods are called in a specific order, and therefore the tests that come from this approach start becoming less results-oriented, and rely more on the method verification from the Mocking framework.  He points out these two styles of testing without really saying one is better than the other (he does indicate that he tends to be in the Stub camp, but I think that is a personal choice and level of comfort thing), beyond pointing out that relying on the results of the test tends to be more in line with the pure TDD way of doing things.

Now, I had read this article before I started using mocks within my project.  I thought about using stubs throughout, but since I was testing data access code, I would have a lot of methods to implement in my stub objects that wouldn't really be part of what I was testing, so it seemed a large waste of my time.  As I started implementing mocks in the tests, I paid attention to how I was testing to see if I was becoming a "Mockist" in the Fowler sense.  Overall I would say that I am not, currently, a "Mockist".  I'm still overwhelmingly validating the results of calls based on the methods I'm testing, and just using the mocks to feed appropriate values into the classes I'm trying to test.  As a matter of fact, I could probably remove the call to _mocks.VerifyAll() at the end of my tests, since I don't really care.  I can say, though, that the ability to verify what is being called with what arguments has been extremely useful in my data access testing space.  I've basically got objects which are making calls to stored procs on Oracle to do my data work. The DAL is a real simple deal that doesn't have much in the way of smarts, but works well enough for a small project.  Because of the fact that I'm making stored proc calls to the database, I can now use the mocks to make sure that when I call the Save() method on my User object (for example), It's calling ExecuteNonQuery() with the proc name of SAVE_USER.  I can also verify that all of the input an output parameters are being set correctly, which is a big consideration when adding a property to the data objects.  In that way I can know that my Save() method is doing what it is supposed to even though it returns no value.  This checking could probably be done by stubbing the EnterpriseLibrary Database and DBCommand objects, and then setting values within my stub object, which I could verify using an Assert call, but that seems like an awful lot of work when I have the option to simply set expectations, and then do a VerifyAll().

I think the Fowler article may be making much of a practice which is not that common among people using mocks in TDD.  Or maybe there is a slow creep that happens to the developer after months and years of using mocks in their tests that turn them into Mockists.  Personally I find that there is a very broad and comfortable middle ground which allows me more flexibility to express my intent quickly and concisely.  And after all, expressing intent is one of the major boons of TDD.

Tags:

Genuine Advantage Notification - WTF?

 

This morning I was greeted by a friendly message from Windows Update saying I had updates ready to install.  Because I'm the curious sort who likes to see how many issues MS has to deal with regularly, I decided to use "Advanced" mode to see what the updates were (By "Advanced" of course it means anyone who is concerned about what is getting installed on their machines...I've seen I Robot, I know that one day the great machine can decide the only way to save us from our selves is to format our hard drives).

What greeted me was the "Genuine Advantage Notification" update.  Apparently this is a little guy that sits in memory and periodically checks to make sure my version of Windows does not suddenly become pirated.  WTF?  Is this really a problem?  Sure I can maybe see if someone decides to upgrade to a pirated version of Vista, instead of paving their machine like normal people do, this might come in handy....that's assuming though that the tool gets picked up by the upgrade process, and that someone who purchases a pirated copy of Vista is the sort of person who would leave a gem such as this one installed on their machine.

Okay, okay, I know that there are probably cases of normal users going to Thailand and thinking to themselves "Well, here is a booth with Windows Vista DVDs, and they are only wanting $30 for it...that's way cheaper than in the US...must be the currency conversion rate", and so they accidentally get themselves a pirated copy of Windows.  I would think that most people who are grabbing pirated copies of their OS are doing it because they don't want to pay for the full version, and they are under no false pretenses about the "Genuineness" of the product.

The best part of this utility is the fact that once it figures out that your OS has become pirated, it will "help you obtain a licensed copy".  That makes me feel really confident about having this thing running all the time.

Tags: