Question

Background:

Here's the code for what I'm currently working on. First, the base class, which is an account class that holds information about the account and has some methods that for the most part change the values of the class's properties.

public class Account {
    private string _username; [...]

    public string Username { get { return _username; } } [...]

    public Account() { }

    public Account(string[] args) { [...] }

    public virtual void ChangePassword(string newPassword) { [...] }
}

Then, I have another class for when the account has been created, which I have named ActiveAccount. This contains most of the logic for the actions I want to use for the account that are only possible once the account has been created. Some classes need not to be included to explain the question; use your imagination to assume what those classes may do:

public class ActiveAccount : Account
{
    private List<Conversation> _conversations; [...]

    public List<Conversation> Conversations { get { return _conversations; } } [...]

    private ActiveAccount() { }

    public static ActiveAccount CreateAccount(Account account)
    {
        // Navigate to URL, input fields, create account, etc.
    }

    public override void ChangePassword(string newPassword)
    {
        // Navigate to URL, input fields, change password, etc.

        // Update property using base method, if no errors.
        base.ChangePassword(newPassword);
    }
}

I've used a static factory method for two reasons. 1) I want customiseable and extensible construction of an object (for example, in the future I might have an AccountTemplate from which I provide generic information to create accounts; I can easily create another static factory method overload with an AccountTemplate parameter), and 2) having a parameterless constructor allows me to serialize this object more easily into XML/JSON.

Question:

However, it's come to my attention that I could just as easily have a public constructor that accepts an Account parameter, performs the logic and can be extended with overloads just as easily. I can keep my private parameterless constructor to prevent parameterless construction and allow serialization.

I'm quite new to programming. What I'm wondering is if there is a specific reason to use static factory methods instead of public constructors, as explained above. And what's the preferred way of doing what I want to do?

Was it helpful?

Solution

I wouldn't call what you used a static factory. In my eyes it's a "named constructor" since it resides in the class itself and just creates an object of that particular class.

It is often used to make the operation easier to understand, e.g. compare

int value = Int32.Parse(someString);
int value = new Int32(someString); // doesn't really exist

The first version makes it clear that it parses the input string, the second is far less verbose.

Update: one important difference between constructors and static methods like Int32.Parse is that static methods can chose whether to return null in case an error occured or throw an exception. A constructor can only throw an exception or - and I wouldn't recommend that - leave the object in some sort of limbo state where it is only half-initialized.


A static factory is used to decouple classes, and to make it easier to change the implementation, for example instead of instantiating a database connection using the new operator in your code every time you need a database connection you use a factory method that returns an interface:

SqlConnection myConnection = new SqlConnection(connectionString);
IDbConnection myConnection = myFactory.CreateConnection();

The advantage is that by simply changing the CreateConnection method you can make global changes to your entire project, swapping databases servers or even database providers without having to change your code in all the places where you actually use the database connection.

OTHER TIPS

I would advise you to read the .NET constructor guidelines. There are some points that probably leads to choosing a static factory instead of a constructor in your case. Namely

Do minimal work in the constructor. Constructors should not do much work other than to capture the constructor parameters. The cost of any other processing should be delayed until required.

and

Consider using a static factory method instead of a constructor if the semantics of the desired operation do not map directly to the construction of a new instance, or if following the constructor design guidelines feels unnatural.

There are my consideration about when you need to prefer a static factory method and when a constructor.

1) Use a static factory method if you need to do some additional actions/initializations that cannot be done by a constructor. For example if you need to publish newly created ActiveAccount object (e.g. SomePublicList.Add(ActiveAccount); ) then it's a bad practice to publish it from within it's own constructor.

2) Think about inheritance. If you need to create a descendent class (e.g. NewActiveAccout) for ActiveAccount then you need to provide a non-private constructor in ActiveAccount. Perhaps you need to prefer a constructor to a factory method in that case.

3) If you need to pass some parameters to the base class (Account) constructor then you need to implement a constructor in ActiveAccount because you can't pass parameters to base class constructor from a static factory method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top