Design Patterns : #3 Factory Method Pattern

No alt text provided for this image


When use Factory method over Singleton Pattern?

Singleton and Factory method both are in a way hard coding instance creation then when do we use factory method?

  1. A singleton pattern ensures that you always get back the same instance of whatever type you are retrieving, whereas the factory pattern generally gives you a different instance of each type.
  2. Singleton: The purpose of the singleton is where you want all calls to go through the same instance. wherever it is important only one known instance interacts with the resource. This does make it less scalable. Factory Method: The purpose of the factory is to create and return new instances. Often, these won't actually be the same type at all, but they will be implementations of the same base class. However, there may be many instances of each type.
  3. Factory method and Singleton can be used together: A singleton relates to the life-cycle of the object (only one instance for life of the application). A factory's job is to return objects that you require, It will often build a new instance of a type, but not necessarily so; one could move the life-cycle control of the singleton out of the singleton class and put it into a factory instead which could return the same class every time making it essentially a singleton for your application (For code on similar lines, Please refer  Singleton pattern article).

What Factory Method gives us...

  1. Factory Method is to creating objects as Template Method is to implementing an algorithm. A super-class specifies all standard and generic behavior (using pure virtual "placeholders" for creation steps), and then delegates the creation details to subclasses that are supplied by the client.
  2. Factory Method makes a design more customizable and only a little more complicated. Other design patterns require new classes, whereas Factory Method only requires a new operation.
  3. People often use Factory Method as the standard way to create objects; but it isn't necessary if the class that's instantiated never changes, or instantiation takes place in an operation that subclasses can easily override (such as an initialization operation).
  4. Factory Method is similar to Abstract Factory but without the emphasis on families.
  5. Factory Methods are routinely specified by an architectural framework, and then implemented by the user of the framework.

We are seeing two different Variety of Factory method in Class Diagram, Lets see Code for each one. Code is self-explanatory.

Green Color Factory Class in Class Diagram

class Button {
public:
	virtual void paint() = 0;
};
 
class OSXButton: public Button {
public:
	void paint() {
		std::cout << "OSX button \n";
	}
};
 
class WindowsButton: public Button  {
public:
	void paint() {
		std::cout << "Windows button \n";
	}
};
 
class GUIFactory {
public:
	virtual Button *createButton(char *) = 0;
};


class Factory: public GUIFactory {
public:
	Button *createButton(char *type) {
		if(strcmp(type,"Windows") == 0) {
			return new WindowsButton;
		}
		else if(strcmp(type,"OSX") == 0) {
			return new OSXButton;
		}
	}
};


int main()
{
	GUIFactory* guiFactory;
	Button *btn;


	guiFactory = new Factory;


	btn = guiFactory->createButton("OSX");
	btn -> paint();
	btn = guiFactory->createButton("Windows");
	btn -> paint();
    return 0;
	
}

Brown Color Factory Class in Class Diagram

class Button {
public:
	virtual void paint() = 0;
};
 
class OSXButton: public Button {
public:
	void paint() {
		std::cout << "OSX button \n";
	}
};
 
class WindowsButton: public Button  {
public:
	void paint() {
		std::cout << "Windows button \n";
	}
};
 
class iPhoneButton: public Button {
public:
	void paint() {
		std::cout << "iPhone button \n";
	}
};


class GUIFactory {
public:
	virtual Button *createButton(char *type) {
		if(strcmp(type,"Windows") == 0) {
			return new WindowsButton;
		}
		else if(strcmp(type,"OSX") == 0) {
			return new OSXButton;
		}
		return NULL;
	}
};


// Extend class to add new object creation
class Factory: public GUIFactory {
		Button *createButton(char *type) {
		if(strcmp(type,"Windows") == 0) {
			return new WindowsButton;
		}
		else if(strcmp(type,"OSX") == 0) {
			return new OSXButton;
		}
		else if(strcmp(type,"iPhone") == 0) { 
			return new iPhoneButton; // new object added here
		}
	}
};


int main()
{
	GUIFactory* guiFactory;
	Button *btn;


	guiFactory = new Factory; // IMP


	btn = guiFactory->createButton("OSX");
	btn -> paint();
	btn = guiFactory->createButton("Windows");
	btn -> paint();
	btn = guiFactory->createButton("iPhone"); // Extending new object creation
	btn -> paint();
  
    return 0;
}
   


Thumb Rule

  1. Often, designs starts using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed.
  2. Prototype doesn't require subclassing, but it does require an Initialize operation. Factory Method requires subclassing, but doesn't require Initialize.
  3. Factory Method: creation through inheritance. Prototype: creation through delegation.
  4. Abstract Factory classes are often implemented with Factory Methods, but they can be implemented using Prototype.
  5. Some Factory Method experts recommend that all constructors should be private or protected. Factory method can dictate a new object or recycles an old one.
  6. The new operator considered harmful. There is a difference between requesting an object and creating one; The new operator always creates an object, and fails to encapsulate object creation. A Factory Method enforces that encapsulation, and allows an object to be requested without coupling to the act of creation.

Hope it helps...

要查看或添加评论,请登录

社区洞察

其他会员也浏览了