When to use Factory method pattern?

2019-01-21 03:50发布

问题:

When to use Factory method pattern?

Please provide me some specific idea when to use it in project? and how it is a better way over new keyword?

回答1:

Although this isn't necessarily it's primary use, it's good for something where you have specialized instances of a class:

public ITax BuildNewSalesTax()
public ITax BuildNewValueAddedTax()

You need both methods to build a tax object, but you don't want to have to depend on using "new" everytime because the constructors may be complex. This way I encapsulate all of the changes into a single method that is clear to others for future maintenance.



回答2:

I have two cases where I tend to use it:

  1. The object needs to be initialized in some specific manner
  2. When I want to construct a specific type based on an abstract type (an abstract class or an interface).

Examples:

  1. First case could be that you want to have a factory creating SqlCommand objects, where you automatically attach a valid SqlConnection before returning the command object.

  2. Second case is if you have an interface defined and determine at execution time which exact implementation of the interface to use (for instance by specifying it in a configuration file).



回答3:

Use a factory method (not abstract factory) when you want to reuse common functionality with different components.

Example: Imagine you have an M16 rifle. Something like this:

public class M16
{
    private Scope scope = new StandardScope();
    private SecondaryWeapon secondary = new Bayonet();
    private Camouflage camo = new DesertCamo();

    public double getMass()
    {
        // Add the mass of the gun to the mass of all the attachments.
    }

    public Point2D shootAtTarget(Point2D targetPosition)
    {
        // Very complicated calculation taking account of lots of variables such as
        // scope accuracy and gun weight.
    }
}

You may be satisfied with it for a while, thinking that you wont want to change anything. But then you have to do a secret nightime stealth mission in the jungle, and you realise that your attachments are completely inappropriate. You really need a NightVision scope, JungleCamo and a GrenadeLauncher secondary weapon. You will have to copy past the code from your original M16......not good extensibility.....Factory Method to the rescue!

Rewrite your M16 class:

public abstract class M16
{
    private Scope scope = getScope();
    private SecondaryWeapon secondary = getSecondaryWeapon();
    private Camouflage camo = getCamouflage();

    public double getMass()
    {
        // Add the mass of the gun to the mass of all the attachments.
    }

    public Point2D shootAtTarget(Point2D targetPosition)
    {
        // Very complicated calculation taking account of lots of variables such as
        // scope accuracy and gun weight.
    }

    // Don't have to be abstract if you want to have defaults.
    protected abstract Scope getScope();
    protected abstract SecondaryWeapon getSecondaryWeapon();
    protected abstract Camouflage getCamouflage();
}


//Then, your new JungleM16 can be created with hardly any effort (and importantly, no code //copying):

public class JungleM16 : M16
{
    public Scope getScope()
    {
        return new NightVisionScope();
    }

    public SecondaryWeapon getSecondaryWeapon()
    {
        return new GrenadeLauncher();
    }

    public Camouflage getCamouflage()
    {
        return new JungleCamo();
    }
}

Main idea? Customise and swap out composing objects while keeping common functionality.

An actually useful place to use it: You have just designed a really cool GUI, and it has a really complicated layout. It would be a real pain to have to layout everything again if you wanted to have different widgets. So.....use a factory method to create the widgets. Then, if you change your mind (or someone else want to use your class, but use different components) you can just subclass the GUI and override the factory methods.



回答4:

You can refer to section 9.5 Factories from Framework Design Guidelines 2nd Edition. Here is quoted set of guidelines with respect to using factories over constructors:

DO prefer constructors to factories, because they are generally more usable, consistent, and convenient than specialized construction mechanisms.

CONSIDER using a factory if you need more control than can be provided by constructors over the creation of the instances.

DO use a factory in cases where a developer might not know which type to construct, such as when coding against a base type or interface.

CONSIDER using a factory if having a named method is the only way to make the operation self-explanatory.

DO use a factory for conversion-style operations.

And from section 5.3 Constructor Design

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



回答5:

I am using Factory pattens when

  1. When a class does not know which class of objects it must create.

  2. A class specifies its sub-classes to specify which objects to create.

  3. In programmer’s language (very raw form), you can use factory pattern where you have to create an object of any one of sub-classes depending on the data provided.



回答6:

Factory method pattern can be used when there is a need to generate objects that belong to specific family. Along side this requirement, you also want to keep the decisions made regarding object instantiation in one place.

Please refer the following link for more details.

http://xeon2k.wordpress.com/2010/11/27/factory-method-pattern/



回答7:

Use the Abstract Factory pattern when a system should be independent of how its products are created, composed, and represented. a system should be configured with one of multiple families of products. a family of related product objects is designed to be used together, and you need to enforce this constraint. you want to provide a class library of products, and you want to reveal just their interfaces, not their implementations.



回答8:

Factory pattern deals with the instantiation of object without exposing the instantiation logic. In other words, a Factory is actually a creator of object which has common interface.

It lets the subclass to decide which class to be instantiated.

Consider the following example:

namespace TestApp
{
    class Program
    {
        static void Main(string[] args)
        {
            //Store is ordering the factory to get office shoes
            Shoe shoe = ShoeFactory.GetShoes("OFFICE");
            Console.WriteLine(shoe.GetType()); //Will be office shoes

            //Store is ordering the factory to get sports shoes
            shoe = ShoeFactory.GetShoes("SPORTS");
            Console.WriteLine(shoe.GetType()); //Will be sports shoes
        }
    }

    //This is the factory supplying shoes. It can supply sports shoes or office shoes
    //based on demand
    class ShoeFactory
    {
        public static Shoe GetShoes(string strShoeType)
        {
            switch (strShoeType)
            {
                case "SPORTS": return new SportShoe();
                    break;
                case "OFFICE": return new OfficeShoe();
                    break;
                default:
                    return null;
            }
        }
    }

    //This is an abstract class representing product family
    //In this example, its shoe
    public abstract class Shoe
    {

    }

    //Office shoe is a concrete class belongs to shoe family
    class OfficeShoe : Shoe
    {   

    }

    //Sports shoe is a concrete class belongs to shoe family
    class SportShoe : Shoe
    {

    }
}


回答9:

It's better to have a factory method pattern vs new keyword. The idea is to move complete instantiation of objects outside the business logic. This principle is the crux of dependency injection. And, the work of the factory method can be delegated to a Dependency Injection Framework like Spring.net or Castle Windsor at a later point.



回答10:

To answer the second part of you question from my opinion, I think the reason it's better than the 'new' keyword is that the factory method reduces the dependancy on constructors of particular classes. By using a factory method, you delegate the creation of the object in question to someone else, so the caller doesn't need teh knowledge of how to create the object.



回答11:

I think its when you want your application to be loosely coupled and extensible in future without coding changes.

I have written a post on blog as to why i choose the factory pattern in my project and may be it can give you more insight. The example is in PHP but i think its applicable in general to all languages.

http://www.mixedwaves.com/2009/02/implementing-factory-design-pattern/