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?
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.