views:

102

answers:

3

I am struggling to understand why the initialization of pprocessor, below, is written like this:

class X
{
...
private:
   boost::scoped_ptr<f_process> pprocessor_;
};

X:X()
 : pprocessor_( f_process_factory<t_process>().make() ) //why the factory with template
{...}

instead of just writing

X:X()
 : pprocessor_( new t_process() ) 
{...}

Other relevant code is:

class f_process {
   ...
};

class t_process : public f_process {
   ...
};


//

class f_process_factory_base {
public:
   f_process_factory_base() { }
   virtual ~f_process_factory_base() = 0 { }
   virtual f_process* make() = 0;
};

template < typename processClass >
class f_process_factory : public f_process_factory_base {
public:
   f_process_factory() { }
   virtual ~f_process_factory() { }
   virtual processClass* make() { return new processClass(); }
};

The guy who wrote the code is very clever so perhaps there is a good reason for it.
(I can't contact him to ask)

+2  A: 

This look like he is using the factory design pattern to create new instances of t_process. This will allow you to delegate the responsibility of creating different types of t_process away from class X

Rohan West
except that it doesn't create different types of `t_process`. It calls a `t_process` factory that calls `new t_process();`, the `t_process` class is concrete.
Stephen
How can you be sure what factory it is using, what if there are multiple factories? After all the factory methods are not static. It could be pointing to a different class other that the one mentioned in the example code and using polymorphism to create the process instance.
Rohan West
@Rohan : I can be sure because it constructs a temporary `t_process` factory right there in the initialization of `pprocessor_` then calls `make()` on it :)
Stephen
@Stephen : Ah, your right, thought it was a variable.
Rohan West
+1  A: 

Well, in this case it doesn't make much sense, unless the author expects the default factory's definition will be updated sometime in the future. It would make sense, though, if the factory object were passed in as a parameter; a factory gives you more flexibility in constructing an object, but if you instantiate the factory at the same place that you use it, then it really doesn't provide an advantage. So, you're right.

Michael Aaron Safyan
+2  A: 

As it is, it seems kinda pointless, but I can think of a few possible uses that aren't shown here, but may be useful in the future:

  • Memory management: It's possible that at some point in the future the original author anticipated needing a different allocation scheme for t_process. For example, he may want to reuse old objects or allocate new ones from an arena.

  • Tracking creation: There may be stats collected by the f_process_factory objects when they're created. Maybe the factory can keep some static state.

  • Binding constructor parameters: Perhaps a specialization of the f_process_factory for t_process at some point in the future needs to pass constructor parameters to the t_process creator, but X doesn't want to know about them.

  • Preparing for dependency injection: It might be possible to specialize these factories to return mocks, instead of real t_process. That could be achieved in a few ways, but not exactly as written.

  • Specialized object creation: (This is really just the general case for the previous two), there may be specializations of t_process that get created in different circumstances - for example, it might create different t_process types based on environmental variables or operating system. This would require specializations of the factory.

If it were me, and none of these sound plausible, I'd probably rip it out, as it seems like gratuitous design pattern usage.

Stephen