Factory vs instance constructors
Solution 1
Note: What you have is not a static constructor, it's a static function that creates the instance rather than calling the instance constructor yourself. A static constructor is a different thing entirely.
The factory pattern is a classic example of using a function (static or not) to instantiate a type rather than using the constructor directly. Note that the actual instance constructor will get called no matter what, but the static function provides a layer of indirection that allows it to return an instance of any type that either is or inherits from the return type, rather than only instances that are the return type.
For example:
public abstract class BaseClass
{
public static BaseClass Create(int parameter)
{
if (parameter == 1)
{
return new Class1();
}
else
{
return new Class2();
}
}
}
internal class Class1 : BaseClass
{
//code here ...
}
internal class Class2 : BaseClass
{
//code here ...
}
This allows you to hide Class1
and Class2
from external assemblies while still allowing the consumer to deal with something specialized.
Solution 2
I was researching this very point and came across this question but didn't feel it had been answered fully. However, I did find this handy article - Design Guidelines Update: Factories vs. Constructors - by Krzysztof Cwalina (a a Principal Architect on the .NET Framework). It is worth reading the entire article, but here is a brief summary of the main points:
The most common and consistent way to create an instance of a type is via its constructor. However, sometimes a preferable alternative is to use the Factory pattern.
Do prefer constructors over Factories as they are generally more consistent and convenient than specialized construction mechanisms.
Do implement Factory operations as methods, not properties.
Do return instances as method return values, not as out parameters.
Consider using a Factory if you need more control over the creation patterns of instances.
Consider naming Factory methods by concatenating “Create” and the name of the type being created.
Consider naming Factory types by concatenating the name of type being created and “Factory.”
Do not implement your Factory using a static method if the construction operation must be available for subclasses to specialize.
Do use a Factory for conversion style operations.
Do use a Factory if an operation requires parameter information which feels unnatural to pass to a constructor.
Do not use a Factory in situations where the creation operation will be used as a core scenario for instantiation of a type. In these situations, discoverability and consistency are paramount.
Consider using a constructor instead of a Factory. Only after this thought process should you proceed with the implementation of a Factory.
Factories are also often handy to enable type specialization through polymorphism.
Do use a Factory if API users will be coding to a base class or interface whose implementation is subject to change over time.
Do use Factory methods in cases where a developer might not know which type to construct, for instance when coding against a base type or interface.
Do implement Factory operations as virtual instance methods rather than static if they must support polymorphic extension.
Do use the Singleton pattern for Factories which are instance based so as not to force developers to instantiate a Factory type just to invoke one of its members.
Do use a Factory method if a constructor would be insufficient to describe the operation being performed, and the additional information gained from an individually named Factory makes an operation’s purpose clearer.
Solution 3
Another common case where factory methods help (in languages like C# which don't support type inference from constructor) is when you have to minimize type parameter specification. Consider the common case of Tuple
class. You can either do:
new Tuple<int, int>(1, 1); //constructor call
or
Tuple.Create(1, 1); //factory pattern.
Solution 4
The static Create
method can instantiate and return:
- A
MyClass
instance - An instance of any subclass of
MyClass
null
Solution 5
The factory method is often used to hide the exact type of the object being created. An abstract class can have a static factory method, which then selects the concrete derived class to instantiate depending on some condition. Only the abstract base class is publicly documented. This leaves the library supplier some freedom to change the exact type being instantiated without breaking existing code.
An example from the .NET framework is the static factory methods on the Expression
class.
Comments
-
Neil N almost 2 years
I can't think of any reasons why one is better than the other. Compare these two implementations:
public class MyClass { public MyClass(string fileName) { // some code... } }
as opposed to:
public class MyClass { private MyClass(){} public static MyClass Create(string fileName) { // some code... } }
There are some places in the .Net framework that use a static method to create instances. At first I was thinking, it registers it's instances to keep track of them, but regular constructors could do the same thing through the use of private static variables.
What is the reasoning behind this style?
-
Nathan Taylor almost 14 yearsTechnically, what he has is code that won't compile because his static Create method doesn't actually return anything. :)
-
Adam Robinson almost 14 years@Nathan: Yes, though I'm fairly certain that his code is an example rather than an actual code snippet (hence the
// some code...
blocks). -
Neil N almost 14 yearsAs I pointed out in the question, this is something regular instance constructors could do as well.
-
Nathan Taylor almost 14 yearsIndeed, I'm just being somewhat cynical. :)
-
supercat almost 13 yearsSlight addendum: in either of the first two cases, the object returned may be a newly-created object instance or a shared object instance. The distinction may be important if other code checks for reference equality.
-
Icemanind over 9 years@AdamRobinson - You said
The factory pattern is a classic example of using a function (static or not) to instantiate a type
. Wouldn't it have to be static? Because if it had no constructors, how could you call any methods? -
Adam Robinson over 9 years@icemanind: Something like
DataTable.NewRow
comes to mind. In the scenario where you're working with typedDataSet
s, each table has two types: a type that inherits fromDataTable
and a type that inherits fromDataRow
(to provide strongly-typed properties to read/write against the loosely-typed backing store of the table). The table type would overrideNewRowFromBuilder
to instantiate the inherited row type and return it. CallingNewRow
on the table then trickles down to this and you have the table instantiating the row for you (via instance method) rather than using the constructor -
Icemanind over 9 years@AdamRobinson - Thanks for the clarification. I see what you mean now. It seems like a very limited scenario though, but I do understand.
-
Adam Robinson over 9 yearsYeah, if you're suggesting that most factory implementations involve a static function doing the constructing, then I'd wager you're right.
-
sc911 over 2 yearsUpdated Link: docs.microsoft.com/en-us/archive/blogs/kcwalina/…