5

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?

3
  • 5
    What you are calling the "Factory Method Pattern" is actually an Abstract Factory Pattern. What you are calling the "Factory Pattern" is sometimes called the Factory Method Pattern. Commented Apr 6, 2017 at 15:55
  • I will call the first one "Static Simple Factory". The second one is a strange abstract factory which just produce one type of product. But the second one looks good to me.
    – NingW
    Commented Apr 7, 2017 at 8:01
  • here i show code with two approach. first one is static factory and second one is factory method pattern but still not clear when one should think about factory method pattern instead of static factory. if possible come with discussion. thanks all
    – Mou
    Commented Apr 11, 2017 at 12:34

2 Answers 2

7

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.

8
  • thanks for answer. you forgot to show how to call ShipperFactory CreateInstance. how to use this code.
    – Mou
    Commented Apr 11, 2017 at 10:49
  • this code is not clear. please explain me. public static readonly IDictionary<Shipper, Func<IShip>> Creators = new Dictionary<Shipper, Func<IShip>>() { { Shipper.UPS, () => Create<ShipperUPS>() }, { Shipper.FedEx, () => Create<ShipperFedEx>() }, { Shipper.Purolator, () => Create<ShipperPurolator>() } };
    – Mou
    Commented Apr 11, 2017 at 10:50
  • you did not follow my code rather you refactor my code lot. would you tell me my approach of code was wrong ? in my post i have show two approach one is static factory and one is factory method pattern. if possible tell me what was wrong in my code. discuss in details. thanks
    – Mou
    Commented Apr 11, 2017 at 10:51
  • 1
    why u use interface and abstract class both when we can get our job done by interface?
    – Mou
    Commented Apr 11, 2017 at 12:09
  • The abstract class allows you to factor the common semantic (methods &/or properties) shared by all IShipper implementation, while leaving open (ie, abstract) the others that must / can only be defined at the level of the derived classes. As for the use of the CreateInstance method, it is the same as yours: eg, ShipperFactory.CreateInstance(Shipper.FedEx)
    – YSharp
    Commented Apr 12, 2017 at 18:07
7

In both situations, the Factory pattern is being badly implemented. I would not use either pattern as coded here in production code.

In theory, the only practical difference between the Factory and Factory Method pattern is what the "dependent object" that needs a way to create things has to do this. In the Factory pattern, the dependent object has an instance of the factory class. In the Factory Method pattern, the dependent object has a reference directly to a method it can call, in the form of a delegate.

The first example is to be avoided because it uses a switch statement. Switch exists for good reasons, however its use in modern C# is a code smell, because there are better options for many of its use cases, including this one. In this situation, the switch statement has to be changed every time a new IShip implementation is added to the codebase. So, when you add DHL or USPS as a shipping option, not only do you need a new IShip, you need to modify the factory. This is generally to be avoided.

In the second pattern, you essentially have a factory class for each IShip implementation. Now, when you create a new IShip() implementation, you need a new IShipFactory implementation. That's even more boilerplate and more changes needed to the codebase. In addition, you're now tightly coupling not to the IShip implementation's constructor (which is what the Factory patterns avoid), but to the IShipFactory's constructor; you're really no better off, you might as well just new up the IShip instead of the Factory.

What you need are some additional patterns, namely the Strategy pattern and the Dependency Injection pattern.

The Strategy pattern is an umbrella term for any object that encapsulates a ruleset for choosing the best implementation of a necessary dependency. In this case, it would use the enumeration value provided. The ShipperFactory.CreateInstance() method is an example of a Strategy pattern, but there is a better implementation for your use case; the delegate dictionary:

public interface IShip
{
    Shippers Shipper { get; }

    void Ship();
}

public enum Shippers
{
    UPS,
    FedEx,
    Purolator,
}

public class UPSShipper : IShip
{
    public Shippers Shipper => Shippers.UPS;
    public void Ship() {  /*TODO: Implement*/ }
}

public class FedExShipper : IShip
{
    public Shippers Shipper => Shippers.FedEx;
    public void Ship() {  /*TODO: Implement*/ }
}

//Add additional implementations

public class ShipperFactory
{
    public Dictionary<Shippers, Func<IShip>> shipperCreators { get; private set; }
    public ShipperFactory()
    {
        //Here, we use reflection and Linq to find all IShip implementations;
        //other methods to dynamically set up the dictionary exist
        shipperCreators = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => typeof (IShip).IsAssignableFrom(t) && t.IsInterface == false)
            .Select(t => new Func<IShip>(() => Activator.CreateInstance(t) as IShip))
            .ToDictionary(f => f().Shipper);
    }

    public IShip CreateInstance(Shippers type)
    {
        return shipperCreators[type]();
    }

    public Func<IShip> GetFactoryMethod(Shippers type)
    {
        return shipperCreators[type];
    }
}

The first change is to the IShip implementation itself; not only does it identify the type of shipper used by its own object name, it also exposes a property (a "discriminator") that identifies the implementation even behind the abstraction of an IShip. This allows each implementation to be self-identifying, which we use when setting up the factory.

The factory itself uses reflection, identifying the types contained in the same assembly as the factory class itself that implement IShip and that are not the factory. It then creates a function for each type that will construct an instance of that type, and executes it once just to generate the enum value to use as a key for the dictionary. as I mentioned in the comments, you don't have to use reflection; you can use a configuration file, or have another object that has even more knowledge pass in the keys and function delegates to the Factory. Reflection is simply an accessible and self-contained way for a factory to find what it needs without having to be told by the developer (which would mean the developer has to tell the factory about every new IShip he creates).

Now, this class can be used either for a Factory Pattern or a Factory Method pattern, based on the method you want to use. For the Factory Pattern, simply call CreateInstance() and pass in the enumeration. For use as a Factory Method generator, call GetFactoryMethod() instead.

Now, to answer the real question, what's the difference? The difference is whether the calling object has or needs any specific knowledge about the type of shipper it should be asking for. If one method needs access to several IShip implementations, it should use the factory. If, however, a method or an object only has to know that it needs an IShip, you can inject the result of GetFactoryMethod as a parameter of the method or the constructor of the object, and then whenever it needs an IShip, it calls the method. No special knowledge is required regarding where the IShip, or even the factory method, come from.

9
  • would u discuss why u use reflection in ctor of ShipperFactory class ?
    – Mou
    Commented Apr 17, 2017 at 14:21
  • Using reflection in this setup allows the factory class to be "self-updating"; there is no need to touch the factory when a new shipper is added to the codebase, provided that the new shipper class is in the same assembly as the factory. This reduces the number of reasons for the factory to change and creates a more maintainable codebase. The tradeoff, with this specific implementation, is reduced performance of the factory methods, since they use Activator.CreateInstance() instead of a native constructor statement.
    – KeithS
    Commented Apr 17, 2017 at 14:31
  • How do you solve when one of the constructors need a parameter while others don't? Why is it a problem, that you have to edit the factory by new types? Aren't your tests covering that case?
    – inf3rno
    Commented Jan 14, 2020 at 5:27
  • @inf3rno If one of these classes takes a parameter that no others do, you have a choice; wrap that class constructor in an adapter that gets the input some other way, or adapt the factory to accept that parameter for all classes, ignoring it for any that don't need it. Either way, you'll need to change how you define the factory methods used by the factory.
    – KeithS
    Commented Jan 15, 2020 at 15:45
  • @inf3rno As for why having to go in and change the factory for every new strategy is bad, there's a basic rule of object-oriented design called the "Open-Closed Principle". Simply put, once an object works properly, any change to how it works risks breaking a use case that used to work (and which you weren't specifically testing in your unit test suite because it used to be identical to another test scenario).
    – KeithS
    Commented Jan 15, 2020 at 15:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.