C# Design Patterns – When to Use Factory Method Pattern Instead of Factory Pattern

cdesign-patterns

I have posted this question on Stack Overflow and there few people suggested to post it here.

I understand the both factory and factory method pattern. In factory pattern we create instance of my classed by another class function dynamically where I pass some parameter to another class function and based on that parameter another class function return right instance of class.

In factory method pattern we have to proceed one further step. In factory method pattern subclass create instance of my class. I do not find a scenario where people has to go for factory method pattern. So please some one come with a scenario where normal factory pattern will not be used rather people prefer to use factory method pattern.

Here I am posting two set of code first one done by factory pattern and second one done by factory method pattern

First set of code where factory pattern used:

public enum Shipper
{
    UPS = 1,
    FedEx = 2,
    Purolator = 3
}

public interface IShip
{
    void Ship();
}

public class ShipperPurolator : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("Purolator ship start");
    }
}

public class ShipperUPS : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("UPS ship start");
    }
}

public class ShipperFexEx : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("FedEx ship start");
    }
}

public class ShipperFactory
{
    public static IShip CreateInstance(Shipper enumModuleName)
    {
        IShip objActivity = null;

        switch (enumModuleName)
        {
            case Shipper.UPS:
                objActivity = new ShipperUPS();
                break;
            case Shipper.FedEx:
                objActivity = new ShipperFexEx();
                break;
            case Shipper.Purolator:
                objActivity = new ShipperPurolator();
                break;
            default:
                break;
        }
        return objActivity;
    }
}

Calling this way:

IShip objActivity = null;

private void btnUPS_Click(object sender, EventArgs e)
{
    objActivity = ShipperFactory.CreateInstance(Shipper.UPS);
    objActivity.Ship();
}

private void btnFedEx_Click(object sender, EventArgs e)
{
    objActivity = ShipperFactory.CreateInstance(Shipper.FedEx);
    objActivity.Ship();
}

private void btnPurolator_Click(object sender, EventArgs e)
{
    objActivity = ShipperFactory.CreateInstance(Shipper.Purolator);
    objActivity.Ship();
}

Now same thing done by factory method pattern where I have to write more code to get the job done

public interface IShip
{
    void Ship();
}

public class ShipperPurolator : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("Purolator ship start");
    }
}

public class ShipperUPS : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("UPS ship start");
    }
}

public class ShipperFedEx : IShip
{
    public void Ship()
    {
        //-- code logic to implement shipping method for Purolator
        MessageBox.Show("FedEx ship start");
    }
}

Factory class start:

public interface IShipFactory
{
    IShip GetShipper();  
}

public class ShipperFexExFactory : IShipFactory
{
    public IShip GetShipper()
    {
        //-- code logic to implement shipping method for Purolator
        //MessageBox.Show("FedEx ship start");
        return new ShipperFedEx();
    }
}

public class ShipperUPSFactory : IShipFactory
{
    public IShip GetShipper()
    {
        //-- code logic to implement shipping method for Purolator
        return new ShipperUPS();
    }
}

public class ShipperPurolatorFactory : IShipFactory
{
    public IShip GetShipper()
    {
        //-- code logic to implement shipping method for Purolator
        return new ShipperPurolator();
    }
}

Calling like this way:

IShipFactory _IShipFactory = null;

private void btnUPS_Click(object sender, EventArgs e)
{
    _IShipFactory = new ShipperUPSFactory();
    _IShipFactory.GetShipper().Ship();
}

private void btnFedEx_Click(object sender, EventArgs e)
{
    _IShipFactory = new ShipperFexExFactory();
    _IShipFactory.GetShipper().Ship();
}

private void btnPurolator_Click(object sender, EventArgs e)
{
    _IShipFactory = new ShipperPurolatorFactory();
    _IShipFactory.GetShipper().Ship();
}

What is prefered way to choose factory method pattern?

Best Answer

Indeed, you have too much of boilerplate going on.

That'd make sense only if you had to stick to C# 1.0.

So, assuming you are implementing in C# 3.0+, a possibly better starting point may be,

(keeping your structuring + naming conventions unchanged, for sake of straightforwardness)

public enum Shipper
{
    UPS,
    FedEx,
    Purolator
}

public interface IShip
{
    //Etc
}

public abstract class ShipperBase : IShip
{
    //Etc
}

public class ShipperUPS : ShipperBase
{
    //Etc
}

public class ShipperFedEx : ShipperBase
{
    //Etc
}

public class ShipperPurolator : ShipperBase
{
    //Etc
}

public class ShipperFactory
{
    public static readonly IDictionary<Shipper, Func<IShip>> Creators =
        new Dictionary<Shipper, Func<IShip>>()
        {
            { Shipper.UPS, () => new ShipperUPS() },
            { Shipper.FedEx, () => new ShipperFedEx() },
            { Shipper.Purolator, () => new ShipperPurolator() }
        };

    public static IShip CreateInstance(Shipper enumModuleName)
    {
        return Creators[enumModuleName]();
    }
}

'Hope this helps.