44

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?

Neil N
  • 24,862
  • 16
  • 85
  • 145
  • Can you give example class where framework does it? – Rohit Jun 02 '10 at 17:09
  • @Rohit: See any of the encryption algorithms in the `System.Security.Cryptography` namespace. – Adam Robinson Jun 02 '10 at 17:11
  • @Rohit: SqlDataReader = new SqlDataReader(); will not compile, giving you the error: "The type 'System.Data.SqlClient.SqlDataReader' has no constructors defined" – Neil N Jun 02 '10 at 17:35
  • 2
    I like using static methods when the name helps to document the nature of the construction functionality, such as `Project.FromFile(string filename)`. – Dan Bryant Jun 02 '10 at 18:23
  • Almost a duplicate: http://stackoverflow.com/questions/194496/static-method-or-instance-constructor – nawfal Jun 02 '13 at 04:28

10 Answers10

56

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.

hdoghmen
  • 3,175
  • 4
  • 29
  • 33
Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
  • Technically, what he has is code that won't compile because his static Create method doesn't actually return anything. :) – Nathan Taylor Jun 02 '10 at 17:17
  • 11
    @Nathan: Yes, though I'm fairly certain that his code is an *example* rather than an actual code snippet (hence the `// some code...` blocks). – Adam Robinson Jun 02 '10 at 17:23
  • Indeed, I'm just being somewhat cynical. :) – Nathan Taylor Jun 02 '10 at 18:06
  • @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? – Icemanind Oct 10 '14 at 23:38
  • @icemanind: Something like `DataTable.NewRow` comes to mind. In the scenario where you're working with typed `DataSet`s, each table has two types: a type that inherits from `DataTable` and a type that inherits from `DataRow` (to provide strongly-typed properties to read/write against the loosely-typed backing store of the table). The table type would override `NewRowFromBuilder` to instantiate the inherited row type and return it. Calling `NewRow` 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 – Adam Robinson Oct 11 '14 at 17:07
  • @AdamRobinson - Thanks for the clarification. I see what you mean now. It seems like a very limited scenario though, but I do understand. – Icemanind Oct 11 '14 at 19:42
  • Yeah, if you're suggesting that most factory implementations involve a static function doing the constructing, then I'd wager you're right. – Adam Robinson Oct 13 '14 at 19:16
22

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.

Dan Diplo
  • 25,076
  • 4
  • 67
  • 89
  • Updated Link: https://learn.microsoft.com/en-us/archive/blogs/kcwalina/design-guidelines-update-factories-vs-constructors – sc911 Feb 27 '22 at 18:24
10

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.
Community
  • 1
  • 1
nawfal
  • 70,104
  • 56
  • 326
  • 368
7

The static Create method can instantiate and return:

  • A MyClass instance
  • An instance of any subclass of MyClass
  • null
ChrisW
  • 54,973
  • 13
  • 116
  • 224
  • 6
    Slight 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. – supercat Jul 22 '11 at 19:17
3

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.

Anders Abel
  • 67,989
  • 17
  • 150
  • 217
1

Methods that do the construction for you are super useful for:

public class Class
    {
        public static List<Class> FromFiles(IEnumerable<String> paths)
        {
            List<Class> instances = new List<Class>();
            foreach (string path in paths)
            {
                instances.Add(new Class() { Path = path });
            }
            return instances;
        }

        public string Path { get; set; }
    }

...since "normal" constructors cannot do this.

1

Not spilling out dependency to assemblies referring your assembly is another reason.

It seems like if calling a constructor for a class in another assembly, your assembly will be required to references all the assemblies that defines any of the types used by any overload. You can workaround this forced dependency by using differently named factory methods.

Example:

Assembly1.dll (requires ref to BarAssembly.dll not so obvious)

class Class1 { 
    void Main(){
        var foo = new Foo();
    }
}

Assembly2.dll (no need for ref to BarAssembly.dll here, as CreateFoo and CreateFooWithBar is not overloads)

class Class2 { 
    void Main(){
        var foo = CreateFoo();
    }
}

FooAssembly.dll (requires ref to BarAssembly.dll obvious)

class Foo { 
    public CreateFoo(){
        ...
    }
    public CreateFooWithBar(Bar bar){
        ...
    }
    public Foo(){
        ...
    }
    public Foo(Bar bar){
        ...
    }
}

BarAssembly.dll

class Bar { 
    public Bar(){
        ...
    }
}

Note: Observed on VS2013 building against .NET Framework 4.5

Daniel
  • 2,167
  • 5
  • 23
  • 44
Jens
  • 2,327
  • 25
  • 34
1

Sometimes it is important to do bookkeeping and/or resource management for every instance of a class created. As a result, it is important that each construction is managed globally and a static method to do the construction will do that nicely.

plinth
  • 48,267
  • 11
  • 78
  • 120
  • 2
    As I pointed out in the question, this is something regular instance constructors could do as well. – Neil N Jun 02 '10 at 17:31
1

As you can see, myClass is not following a "classic" factory pattern (where the class of the instance is not known/exposed outside the factory).

However in this case, the .NET framework team may not be aiming for a factory pattern, but I guess they do not want you to just new up the target class directly with a filename via a constructor. A factory might be overkill if only this class is being provided.

This pattern is sometimes seen in clone() methods, where an object can return an instance which is a kind of duplicate of itself.

Also maybe although the class is public, they might want to do some checks with the instantiation, filename, etc. and if they implemented a factory, the target class could still be created and invoked, bypassing the checks.

Ra.
  • 289
  • 1
  • 3
  • 16
0

You can curry factory methods. Trying to curry a constructor gives you: a factory method.

I use this in some of my code that enumerates the Windows Device Manager tree. One of the classes lists the serial ports, each serial port has a connection factory property which returns a curried factory method with the port address (really ugly PNP device string) stored in internal state while the baud rate, stop bits, parity are all provided later.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720