mercredi 3 avril 2019

The proper usage of a static factory method for creating a DTO object with predefined values

Let's assume we have to create complex DTO object with some predefined (default) values. This object is used for serialization, and a serializer requires a parameterless constructor. To do so, I'd like to use a static factory method, but I have some doubts about the proper usage of this approach.

Please consider the following two examples:

public class Foo
{
    public void DoSomething()
    {
        // the first way of creating the object
        var addressDtoFirstWay = AddressDtoFirstWay
            .CreateWithPredefinedValues();
        addressDtoFirstWay.StreetName = "Street";
        addressDtoFirstWay.HouseNumber = 100;
        addressDtoFirstWay.PostalCode = "1000";

        // the second way of creating the object
        var addressDtoSecondWay = AddressDtoSecondWay
            .CreateWithPredefinedValues("Street", 100, null, "1000");
    }
}

public class AddressDtoFirstWay
{
    public string RecipientName { get; set; }
    public string StreetName { get; set; }
    public int HouseNumber { get; set; }
    public int? FlatNumber { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }
    public string CountryName { get; set; }

    public static AddressDtoFirstWay CreateWithPredefinedValues()
    {
        return new AddressDtoFirstWay
        {
            RecipientName = "John Doe",
            City = "City",
            CountryName = "Country"
        };
    }
}

public class AddressDtoSecondWay
{
    public string RecipientName { get; set; }
    public string StreetName { get; set; }
    public int HouseNumber { get; set; }
    public int? FlatNumber { get; set; }
    public string PostalCode { get; set; }
    public string City { get; set; }
    public string CountryName { get; set; }

    public static AddressDtoSecondWay CreateWithPredefinedValues(
        string streetName,
        int houseNumber,
        int? flatNumber,
        string postalCode)
    {
        return new AddressDtoSecondWay
        {
            RecipientName = "John Doe",
            StreetName = streetName,
            HouseNumber = houseNumber,
            FlatNumber = flatNumber,
            PostalCode = postalCode,
            City = "City",
            CountryName = "Country"
        };
    }
}

In the first example, the factory method initializes only the predefined fields - a user has to initialize the rest of them after object creation. The second example initializes the predefined fields, also the fields which are required, but as a downside, a user has to fill nullable (not required in this case, but required in the other) field flatNumber.

I see both the advantages and disadvantages of these two solutions, but I'm considering which one is more preferred and why. Maybe some other approach will be even better. I'm open to any suggestions, but I want to notice, that the problem it's not that complex that the builder pattern will be applicable.

Aucun commentaire:

Enregistrer un commentaire