Reputation: 4928
I'm currently trying to implement a factory design pattern and somewhat confused as to how this is typically done in C++. I've been referring to this webpage.
So on that webpage, they show an example where they define a factory class called ComputerFactory. This class has a single NewComputer method which is static.
class ComputerFactory
{
public:
static Computer *NewComputer(const std::string &description)
{
if(description == "laptop")
return new Laptop;
if(description == "desktop")
return new Desktop;
return NULL;
}
};
The fact that NewComputer is static means it's not associated with a single instance of ComputerFactory. Thus it is possible to call this method from your code by writing
ComputerFactor::NewComputer("description");
Now I'm curious as to why this needed to be wrapped within a class. Because it's static and really isn't meant to be associated with any class, it would make more sense to do something like
namespace ComputerFactory
{
static Computer *NewComputer(const std::string &description)
{
if(description == "laptop")
return new Laptop;
if(description == "desktop")
return new Desktop;
return NULL;
}
}
So my questions:
Now I believe there are instances where it would make sense to have static methods (e.g. static 'how many of these classes currently exist'), but this doesn't appear to be a situation where it's necessary. Any thoughts?
Edit: So I just had a thought, the example I listed isn't a 'typical' factory method. In practice, it's possible that the factory function is more complex and requires calling other functions (private class methods). In this case, it would make complete sense to wrap the factory into a class such that you could access subfunctions. Is this why factory methods are typically wrapped into classes?
Upvotes: 2
Views: 120
Reputation: 50540
Is the namespace function I described a valid alternative?
Yes.
Would it ever make sense to define a class that only has static methods? It seems like it would make more sense to use a namespace.
There are things you can do with a class that you cannot do with a namespace.
You mentioned one of them (to make use of private members, even though you can use an anonymous namespace to do something similar - not so good actually).
Another relevant example is that you cannot templatize a namespace and this can be quite annoying.
As an example, this happens with a class:
template<typename T>
struct S {
static T f() { return T(); }
// Other member functions
};
// ...
using MyS = S<int>;
MyS::f();
This happens with a template:
namespace N {
template<typename T>
T f() { return T(); }
// Other function template
}
// ...
N::f<int>();
In other terms, you can only define function template if you are using a namespace and it could not be the best solution in any situation.
Moreover, you cannot create an alias as you can do with your class, so you must be explicit about the types at any call place and it can be error-prone and difficult to refactor.
Upvotes: 0
Reputation: 17678
Is the namespace function I described a valid alternative?
Yes
Would it ever make sense to define a class that only has static methods? It seems like it would make more sense to use a namespace.
If the methods are utility methods that can be utilized in many classes, then it would make more sense for them to be in namespace
.
If the methods are specific to the class then make them static
inside the class itself, which would result in better encapsulation.
Upvotes: 2