0

I have a factory method pattern used to create classes and I'd like to validate the input parameters before proceeding to the actual creation. There are two classes that I am dealing with here, A and B, and they each have their own validation. Given that I am already passing the class type (A or B) in my creation template function, I'd like to use that type directly to tell which validation I need to use. I am considering to use template function specialization or dummy input parameter to do that, each with their own pros/cons. Please let me know if either one of them looks more reasonable, or if there are other options too. Thanks!

Oh, and I did consider making the validation as static methods of A or B, but that was not looking good because I am dealing with legacy code and moving that stuff around isn't too straightforward. I also showed this as an option below for completeness-sake though.

Template function specialization:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Template method isn't being leveraged since there are only specializations

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock<T>(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

template <typename T>
bool ValidateBlock (int double);    // don't need an implementation here since 
                                    // all specialization require different validation

template <>
bool ValidateBlock<A> (int, double)
{
    //do validation before creating A
}

template <>
bool ValidateBlock<B> (int, double)
{
    //do validation before creating B
}

Dummy Variable:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Unused dummy variable

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = ValidateBlock(T /*dummy*/, int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

bool ValidateBlock (A/*dummy*/, int, double)
{
    //do validation before creating A
}

bool ValidateBlock (B/*dummy*/, int, double)
{
    //do validation before creating B
}   

Static class method:

Pro: Able to use type passed into the FactoryCreateClass method directly for choosing validation

Con: Harder to make this type of change in legacy code

template <typename T>
void FactoryCreateClass (int, double)
(
    bool bSuccess = T::ValidateBlock(int, double);

    if (bSuccess)
        T* = T::CreateInstance();           
)

static bool A::ValidateBlock (int, double)
{
    //do validation before creating A
}

static bool B::ValidateBlock (int, double)
{
    //do validation before creating B
}
lancery
  • 658
  • 1
  • 6
  • 18

2 Answers2

1

You have forgotten a third alternative: using traits.

template <typename> struct Trait;

template <>
struct Trait<A> {
    static bool Validate(int, double);
};

template <>
struct Trait<B> {
    static bool Validate(int, double);
};

And then:

template <typename T>
void FactoryCreateClass(int i, double d) {
    bool const success = Trait<T>::Validate(i, d);
    // ...
}

But of course, the real question is why not doing the validation in CreateInstance directly ?

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • I abstracted this fact out, but actually A and B inherit from the same base class, and they are actually using the base class' implementation to do the create instance. So the cons of doing it in CreateInstance is much like the cons of the static class method: not so straightforward making this type of change in legacy code. Having said that, it looks like we have at least 3 ways to do this. **Any preference?** Just wanted to hear others' take. – lancery Feb 24 '13 at 23:42
  • @lancery: I usually prefer a traits implementation to functions/methods specializations. More generic, as a trait can be templated while a method cannot be partially specialized. And I also prefer a traits implementation over hacking the class directly because of extensibility (I don't actually have to touch the class this way). – Matthieu M. Feb 25 '13 at 08:10
1

The most appropriate design here is to do the validation inside the CreateInstance method, because the tasks (args validation and instance creation) are strongly coupled, and it is much more readable to have these to things together in one place.

However, it may be the case, you cannot change the code of the CreateInstance method. Well, then I see no significant difference between using function template or dummy variable. The latter is, however, a bit more explicit and thus more readable.

By the way, an unreferenced variable is really not a big problem, you can suppress it, see Disable single warning error, search for UNREFERENCED_PARAMETER on the page

Community
  • 1
  • 1
dkrikun
  • 1,228
  • 1
  • 15
  • 23
  • I abstracted this fact out, but actually A and B inherit from the same base class, and they are actually using the base class' implementation to do the create instance. So the cons of doing it in CreateInstance is much like the cons of the static class method: not so straightforward making this type of change in legacy code. So it looks like your preference is usage of dummy variable because it's more explicit and readable. Thanks for your feedback! – lancery Feb 24 '13 at 23:46