天天看點

Design Pattern - Creational Patterns - Factory Pattern

2007
Design Pattern - Creational Patterns - Factory Pattern
Section 1, Chapter 2

Factory Pattern

Concept

Factories use a base class type to create a class instance. This type can be in the form of either an abstraction or an interface, and based on that type, via creational methods, the factory renders a functional class that inherits or implements this type.

Use

You might use a Factory pattern if you had a lot of creational logic for instances of a class type strewn throughout your code base. You might wish to consolidate this logic into one place for uniformity and maintainability.

Design

Factories can be static or creation only, or repositories, which both create and store references to the created products. But in general, factories provide a way to house the creational aspects of class types.

The Factory pattern has two main components: the Factory and the Product. The factory class is the class that renders the product class. The product class is the class containing data or functionality and is part of a series of class types that can be rendered from a factory method as an instance of an abstract type.

Design Pattern - Creational Patterns - Factory Pattern

Explanation of the UML class diagram:

Illustration

Reflective algorithm

Design Pattern - Creational Patterns - Factory Pattern

reflection in .NET

Type type = typeof(GolfSuit);
Suit suit = (Suit)Activator.CreateInstance(type));
           

Or

Type type = typeof(GolfSuit);
ConstructorInfo info = type.GetConstructor(new Type[]{});
Suit suit = (Suit)info.Invoke(new object[]{}));
           

reflection in Java

Constructor con = Class.forName("GolfSuit").getConstructor(null);
return con.newInstance(null);
           

Reflective Solution example

public sealed class SuitFactory
{
	private Hashtable _registered = new Hashtable();
	private Hashtable _loaded = new Hashtable();
	public Suit CreateSuit(SuitType suitType)
	{
		if(_loaded[suitType] == null)
			Load();
		return (Suit)_loaded[suitType];
	}
	public void Register(SuitType suitType, Type type)
	{
		_registered.Add(suitType, type);
	}
	private void Load()
	{
		foreach(DictionaryEntry obj in _registered)
		{
			Type type = (Type)obj.Value;
			ConstructorInfo info = type.GetConstructor(new Type[]{});
			if(!_loaded.ContainsKey(obj.Key))
				//checks if the class is loaded
				_loaded.Add(obj.Key,(Suit)info.Invoke(new object[]{}));
			//we can use direct reflection in .NET or an activator
			//_loaded.Add(obj.Key,(Suit)Activator.CreateInstance(type));
		}
	}
}
           
SuitFactory factory = new SuitFactory();
factory.Register(SuitType.Armani, typeof(Armani));
factory.Register(SuitType.GolfSuit, typeof(GolfSuit));
factory.Register(SuitType.PlaidBusinessSuit, typeof(PlaidBusinessSuit));
factory.Register(SuitType.StripedBusinessSuit, typeof(StripedBusinessSuit));

Suit suit = factory.CreateSuit(SuitType.StripedBusinessSuit);
           

Inherited algorithm

Design Pattern - Creational Patterns - Factory Pattern
December 2007
Design Pattern - Creational Patterns - Factory Pattern
Section 2, Chapter 5
Design Pattern - Creational Patterns - Factory Pattern

The client declares a Product variable but calls a FactoryMethod to instantiate it. This defers the decision as to which particular product to create.

IProduct The interface for products
ProductA and ProductB Classes that implement IProduct
Creator Provides the FactoryMethod
FactoryMethod Decides which class to instantiate
2016
Design Pattern - Creational Patterns - Factory Pattern
Chapter 12

GoF Definition: Define an interface for creating an object, but let subclasses decide which class to instantiate. The factory method lets a class defer instantiation to subclasses.

Design Pattern - Creational Patterns - Factory Pattern
abstract class IAnimalFactory {
	/*if we cannot instantiate in later stage, we'll throw exception*/
	public abstract IAnimal GetAnimalType(String type) throws Exception;
}

class ConcreteFactory extends IAnimalFactory {
	@Override
	public IAnimal GetAnimalType(String type) throws Exception
	{
		switch (type)
		{
			case "Duck":
			return new Duck();
			case "Tiger":
			return new Tiger();
			default:
			throw new Exception("Animal type : " + type + " cannot be instantiated");
		}
	}
}

class FactoryPatternEx
{
	public static void main(String[] args) throws Exception
	{
		System.out.println("***Factory Pattern Demo***\n");
		IAnimalFactory animalFactory = new ConcreteFactory();
		IAnimal DuckType = animalFactory.GetAnimalType("Duck");
		DuckType.Speak();
		IAnimal TigerType = animalFactory.GetAnimalType("Tiger");
		TigerType.Speak();
		//There is no Lion type. So, an exception will be thrown
		IAnimal LionType = animalFactory.GetAnimalType("Lion");
		LionType.Speak();
	}
}
           
March 25, 2002
Design Pattern - Creational Patterns - Factory Pattern
Chapter 16

Recognizing Factory Method

To summarize, the signs that FACTORY METHOD is at work are that an operation:

  1. Creates a new object
  2. Returns a type that is an abstract class or an interface
  3. Is implemented by several classes

But the spirit of FACTORY METHOD is that the object creator makes a choice about which of several possible classes to instantiate for the client.

The point of the FACTORY METHOD pattern, which the iterator() method exemplifies well, is that clients of the method need not know which class to instantiate.

References:

UML Class Diagrams Reference

Chapter 16