Assume you divide up your systems in Value objects and Services objects (as suggested in "Growing Object-Oriented Software, Guided by Tests". Misko Hevery calls these "newables" and "injectables".
What happens when one of your value objects suddenly needs to access a service to implement it's methods?
Let's say you have a nice simple Value object. It's immutable, holds a few bits of information and that's about it. Let's say we use it something like this:
CreditCard card = new CreditCard("4111-1111-1111-1111", "07/10");
if (card.isValid())
{
// do stuff
}
else
{
// don't do stuff
}
So far so good. isValid()
implements a check digit algorithm on the card number and returns true/false.
Now, let's say I wish to enhance the system by validating the expiry date against the current time. How would you suggest this is done without breaking the Value object/Service object paradim? I should like this class to continue to be unit testable.
CreditCard
now has a dependency, but because of the way it is created it can not be injected, so dependency injection is out.- The
CreditCard
class should not be calling out to Singletons (I am of the position that global access to a Singleton is bad practice) - Putting the behaviour on
CreditCardVerificationService.validateCard()
means all the existing code has to be revisited. The implementation of isValid() is leaking out.
I know there are things that can be done to get around this, but what is the cleanest way?