StartupSvcFactory: why go to the bother?

In a previous post I had said we had

…changed our can’t-mock-dis Startup service from a plain ol’ Singleton…to an Abstract Factory so that…we can now mock out the Startup service and its application-context-creatin’ slowness when we want to.

But some muddled thinking had snuck in on my part: New Ben notes that you don’t need a factory to mock an interface.  Why didn’t we just make the StartupSvc class an interface and mock that interface?  Why go to the bother of creating a StartupSvcFactory as well?

Here’s the proof:

  1. Assume that a factory is not needed
  2. StartupSvc is a class, and getStartupSvc() is a static method on it
  3. You can’t have a static method on an interface (a rule of the Java language), and a factory is not needed (by assumption, #1), so we’ll make getStartupSvc() an instance method of StartupSvc.
  4. To call getStartupSvc() as an instance method, you must already have an instance of a StartupSvc on which to call it, BUT because StartupSvc is a singleton, the only way to get an instance in the first place is by calling getStartupSvc().  When getStartupSvc() as an instance method, there is no way to call it.

∴ a factory is needed.

The factory then takes care of managing the singleton-ness of the StartupSvc and holds the static StartupSvc reference.

How does this help mockability?  Client code then holds a reference to a StartupSvcFactory (interface) and is injected with a StartupSvcFactoryImpl whose getStartupSvc() instance method returns a real StartupSvcImpl — but unit tests inject a mock StartupSvcFactory and can then simulate different behaviors coming from the StartupSvc that are difficult to reproduce, or just slower, with the real thing.

Advertisements

,

  1. #1 by Ben Dean on November 18, 2008 - 11:50 am

    My questions about the necessity of StartupSvcFactory were not based on the assumption that getStartupSvc() could be called from an instance of StartupSvc or from the StartupSvc interface, those are both ridiculous ideas because, as you said in your post, an interface can’t have static methods.

    The reason I was trying to get rid of the StartupSvcFactory was because I didn’t know that there was a need to have getStartupSvc *at all*. In my view of it, step 2 in your argument above should read:

    2. StartupSvc is a class.

    or to be more verbose:

    2. StartupSvc is a class and does not have a getStartupSvc method because nothing outside of the core-fw startup project needs to know about or have access to the StartupSvc.

    The steps of your argument may be valid, but they aren’t what I was arguing for at all. They all make the assumption that getStartupSvc is needed somewhere, which is what I was trying to figure out. I wanted to know why the factory was needed because I was trying to figure out where and why anyone would use StartupSvc outside of the startup project.

  2. #2 by danielmeyer on November 18, 2008 - 12:01 pm

    Oh. :)

    But it was a great chance for me to document for myself why (given that StartupSvc needs to be a singleton) we need a factory! I’m glad to have that written down, since the reasons keep turning to fog in my head otherwise.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s